def loadEdfFile(self): filePath = QFileDialog.getOpenFileName(self, u'Choose edf to load', "./output/", filter="*.edf", selectedFilter="*.edf") if filePath: try: self.tabCount += 1 fileName = ntpath.basename(unicode(filePath)) jobWidget = JobWidget(self.getParams()) jobWidget.jobProgressWidget.hide() jobWidget.runtimeWidget.hide() tabIndex = self.jobTabs.addTab(jobWidget, u"{0}".format(fileName)) self.jobs[self.tabCount] = jobWidget self.showJobGroup(True) self.jobTabs.setCurrentIndex(tabIndex) jobWidget.sigCloseJob.connect( lambda jobIndex=self.tabCount: self.closeJob(jobIndex)) self.uiFinishWait() jobWidget.status = STATUS_FINISHED jobWidget.displayOutput(unicode(filePath)) except Exception as e: message = QErrorMessage(self) message.showMessage( u"Unable to load {0}. Error message: {1}".format( filePath, e.message)) jobWidget.closeJob()
def accept(self): """Acepta el dialogo. Coge la operacion con la que esta trabajando el usuario e inicia el procedimiento de calculo""" from pyrqt.excepciones import OpcionesIncorrectaException import rpy nombre = unicode(self.ui.treeWidget.currentItem().text(0)) widget = self.__widgets["operaciones"][nombre] try: resultado = self.__gestoroperaciones[nombre].procedimiento(widget.seleccion(), widget.opciones()) except OpcionesIncorrectaException: errormessage = QErrorMessage(self) errormessage.showMessage(u"Las opciones no son correctas") #except IndexError: # errormessage = QErrorMessage(self) # errormessage.showMessage(u"Seleccion incorrecta") # LOG.exception("excepcion capturada") except KeyError: QErrorMessage(self).showMessage(u"Hay elementos de la salida sin definir(o mal definidos) en la operación") LOG.exception("Excepción Generada por un módulo de operaciones") except rpy.RException: QErrorMessage(self).showMessage(u"R devolvio un error") log.exception("Excepción de RPY") except AssertionError: QErrorMessage(self).showMessage(u"Error desconocido") else: self.__vsalida.ana_res(resultado) #Añadir a la salida el resultado self.__vsalida.hide() #TODO averiguar como hacer para que recupere el foco sin ocultar la ventana self.__vsalida.show()
def __init__(self, parent=None): """The constructor sets up the MainWindow widget, and connects all necessary signals and slots """ super(MainWindow, self).__init__(parent) self.setupUi(self) # We store the window size to make sure the previous window size # is restored when leaving fullscreen mode. This varible is used # in the toggleFullscreen slot. self.__tmpWinSize = self.size() self.eventFilter = LumaEventFilter(self) self.mainTabs.installEventFilter(self.eventFilter) self.translator = QTranslator() self.languageHandler = LanguageHandler() self.languages = self.languageHandler.availableLanguages #self.__createPluginToolBar() self.__createLoggerWidget() self.__loadSettings() self.__createLanguageOptions() self.setStatusBar(self.statusBar) self.mainTabs.setTabsClosable(True) self.mainTabs.setContextMenuPolicy(Qt.CustomContextMenu) self.mainTabs.customContextMenuRequested.connect( self.__mainTabsContextMenu) self.defaultTabStyle = '' self.lumaHeadStyle = 'background: url(:/icons/luma-gray);\n' + \ 'background-position: bottom right;\n' + \ 'background-attachment: fixed;\n' + \ 'background-repeat: no-repeat;' #Sets up pluginWidget #self in parameter is used to call pluginSelected here... self.pluginWidget = PluginListWidget(self) self.showPlugins() self.welcomeTab = WelcomeTab() self.welcomeTab.textBrowser.setStyleSheet(self.lumaHeadStyle) #This value comes from __loadSettings() #Its a checkbox set in WelcomeTab if self.showWelcomeSettings == 2: self.showWelcome() else: # Let's do some styling of the tab widget when no tabs are opened if self.mainTabs.currentIndex() == -1: self.__setTabWidgetStyle(self.lumaHeadStyle) self.actionShowWelcomeTab.setEnabled(True) self.serversChangedMessage = QErrorMessage(self)
def __init__(self, args): super(QApplication, self).__init__(args) self.error_msg = QErrorMessage() self.ipcon = IPConnection() signal.signal(signal.SIGINT, self.exit_demo) signal.signal(signal.SIGTERM, self.exit_demo) timer = QTimer(self) timer.setSingleShot(True) timer.timeout.connect(self.connect) timer.start(1)
def second_channel_changed(self, index): self.ui.actionStart.setChecked(False) success, index = self.audiobackend.select_second_channel(index) self.settings_dialog.comboBox_secondChannel.setCurrentIndex(index) if not success: # Note: the error message is a child of the settings dialog, so that # that dialog remains on top when the error message is closed error_message = QErrorMessage(self.settings_dialog) error_message.setWindowTitle("Input device error") error_message.showMessage("Impossible to use the selected channel as the second channel, reverting to the previous one") self.ui.actionStart.setChecked(True)
def process(self): search_name = self.searchName.text() layer = self.layerCombo.currentLayer() expression = self.fieldExpressionWidget.currentField()[0] priority = self.priorityBox.value() srid = layer.crs().authid() evaluate_directly = self.evaluateCheckBox.isChecked() if self.projectSearch is None: self.projectSearch = self.project_search_model.addSearch( search_name, layer, expression, priority) else: self.projectSearch.edit(search_name, layer.id(), layer.name(), expression, priority, srid) if evaluate_directly: self.progressBar.setMinimum(0) self.progressBar.setMaximum(layer.featureCount()) self.progressBar.show() self.cancelButton.show() ok, message = self.project_finder.recordSearch(self.projectSearch) self.progressBar.hide() self.cancelButton.hide() self.okButton.show() if not ok: QErrorMessage().showMessage(message) return self.close()
def batchFinished(self): self.base.stop() if len(self.errors) > 0: msg = u"Processing of the following files ended with error: <br><br>" + "<br><br>".join( self.errors) QErrorMessage(self).showMessage(msg) inDir = self.getInputFileName() outDir = self.getOutputFileName() if outDir is None or inDir == outDir: self.outFiles = self.inFiles # load layers managing the render flag to avoid waste of time canvas = self.iface.mapCanvas() previousRenderFlag = canvas.renderFlag() canvas.setRenderFlag(False) notCreatedList = [] for item in self.outFiles: fileInfo = QFileInfo(item) if fileInfo.exists(): if self.base.loadCheckBox.isChecked(): self.addLayerIntoCanvas(fileInfo) else: notCreatedList.append(item) canvas.setRenderFlag(previousRenderFlag) if len(notCreatedList) == 0: QMessageBox.information(self, self.tr("Finished"), self.tr("Operation completed.")) else: QMessageBox.warning( self, self.tr("Warning"), self.tr("The following files were not created: \n{0}").format( ', '.join(notCreatedList)))
def __init__(self, ipcon, uid, version): PluginBase.__init__(self, ipcon, uid, 'DC Brick', version) self.setupUi(self) self.encoder_hide_all() self.dc = BrickDC(uid, ipcon) self.device = self.dc self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(4, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.velocity_slider.sliderReleased.connect(self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished) self.frequency_slider.sliderReleased.connect(self.frequency_slider_released) self.frequency_slider.valueChanged.connect(self.frequency_spin.setValue) self.frequency_spin.editingFinished.connect(self.frequency_spin_finished) self.radio_mode_brake.toggled.connect(self.brake_value_changed) self.radio_mode_coast.toggled.connect(self.coast_value_changed) self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed) self.full_brake_button.pressed.connect(self.full_brake_pressed) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.emergency_signal = None self.under_signal = None self.current_velocity_signal = None self.velocity_reached_signal = None self.qem = QErrorMessage(self) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown) self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN, self.qtcb_emergency_shutdown.emit) self.qtcb_position_reached.connect(self.update_velocity) self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED, self.qtcb_position_reached.emit) self.dc.register_callback(self.dc.CALLBACK_CURRENT_VELOCITY, self.qtcb_position_reached.emit)
def processFinished(self, errors): self.stopProcessing() self.restoreGui() if errors: msg = self.tr("Processing of the following layers/files ended with error:<br><br>") + "<br>".join(errors) QErrorMessage(self).showMessage(msg) QMessageBox.information(self, self.tr("Finished"), self.tr("Processing completed."))
def __init__(self, args): super(QApplication, self).__init__(args) self.error_msg = QErrorMessage() self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION) signal.signal(signal.SIGINT, self.exit_demo) signal.signal(signal.SIGTERM, self.exit_demo) self.make_gui() self.connect()
def loadFields(self, vectorFile): self.attributeComboBox.clear() if not vectorFile: return try: (fields, names) = Utils.getVectorFields(vectorFile) except Utils.UnsupportedOGRFormat, e: QErrorMessage(self).showMessage(e.args[0]) self.inSelector.setLayer(None) return
def __init__(self, parent, app): super(QWidget, self).__init__() self.app = app self.setupUi(self) self.error_msg = QErrorMessage() self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION) self.slider_frame_rate.valueChanged.connect( self.slider_frame_rate_changed) self.spinbox_frame_rate.valueChanged.connect( self.spinbox_frame_rate_changed) self.button_choose.pressed.connect(self.choose_pressed) self.button_show.pressed.connect(self.show_pressed) self.button_default.pressed.connect(self.default_pressed) self.update_frame_rate_timer = QTimer(self) self.update_frame_rate_timer.timeout.connect(self.update_frame_rate) self.default_pressed()
def __init__(self, parent=None): super(DialogService, self).__init__(parent) # All-purpose error popup message: # Used by self.showErrorMsgByErrorCode(<errorCode>), # or self.showErrorMsg(<string>). Returns a # QErrorMessage without parent, but with QWindowFlags set # properly to be a dialog popup box: self.errorMsgPopup = QErrorMessage.qtHandler() # Re-parent the popup, retaining the window flags set # by the qtHandler: self.errorMsgPopup.setParent(parent, self.errorMsgPopup.windowFlags()) # self.errorMsgPopup.setStyleSheet(SpeakEasyGUI.stylesheetAppBG); self.infoMsg = QMessageBox(parent=parent)
def __init__(self, parent=None): super(DialogService, self).__init__(parent) # All-purpose error popup message: # Used by self.showErrorMsgByErrorCode(<errorCode>), # or self.showErrorMsg(<string>). Returns a # QErrorMessage without parent, but with QWindowFlags set # properly to be a dialog popup box: self.errorMsgPopup = QErrorMessage.qtHandler() # Re-parent the popup, retaining the window flags set # by the qtHandler: self.errorMsgPopup.setParent(parent, self.errorMsgPopup.windowFlags()) #self.errorMsgPopup.setStyleSheet(SpeakEasyGUI.stylesheetAppBG); self.infoMsg = QMessageBox(parent=parent)
def processFinished(self, errors): self.stopProcessing() outPath = self.outShape.text() self.restoreGui() if errors: msg = self.tr( "Processing of the following layers/files ended with error:<br><br>" ) + "<br>".join(errors) QErrorMessage(self).showMessage(msg) QMessageBox.information( self, self.tr("Vector Split"), self.tr("Created output shapefiles in folder:\n%s") % (outPath))
def addScanNumbers(self): result = self.range_dialog.exec_() if result == QDialog.Accepted: text = self.range_ui.range_edit.text() if text: not_found = [] numbers = mythen.parse_range_list(text) year, visit = self.getYearAndVisit() progress = QProgressDialog( "Locating scan files from numbers...", "Stop", 0, len(numbers), self) progress.setWindowModality(Qt.WindowModal) progress.forceShow() progress.setValue(0) for n in numbers: progress.setValue(progress.value() + 1) if progress.wasCanceled(): break files = mythen.find_mythen_files( n, visit=visit, year=year) # FIXME needs to be in separate thread(!) if files: files = [f for f in files if f not in self.scans] self.scans.extend(files) self.scans_model.setStringList(self.scans) else: not_found.append(n) progress.setValue(progress.maximum()) if not_found: error = QErrorMessage(self) msg = "The following numbers were not found: " for n in not_found: msg = msg + str(n) + ", " error.showMessage(msg[:-2])
def crear_y_seleccionar_archivo(self, nombre): # Quita la extension si llega a tenerla. nombre = nombre.replace('.py', '') nombre += ".py" nombre_de_archivo = nombre if self.ruta_del_archivo_actual: base_path = os.path.abspath( os.path.dirname(self.ruta_del_archivo_actual)) ruta = os.path.join(base_path, unicode(nombre_de_archivo)) else: ruta = unicode(nombre_de_archivo) if os.path.exists(ruta): self._tmp_dialog = QErrorMessage(self) self._tmp_dialog.showMessage("Ya existe un archivo con ese nombre") else: self._crear_archivo_nuevo_en(ruta) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos()
def loadFields(self, vectorFile=''): self.zfieldCombo.clear() if not vectorFile: return try: (fields, names) = Utils.getVectorFields(vectorFile) except Utils.UnsupportedOGRFormat as e: QErrorMessage(self).showMessage(e.args[0]) self.inSelector.setLayer(None) return ncodec = QTextCodec.codecForName(self.lastEncoding) for name in names: self.zfieldCombo.addItem(ncodec.toUnicode(name))
def input_device_changed(self, index): success, index = self.audio_device.select_input_device(index) self.ui.DeviceList.setCurrentIndex(index) self.fft_plot.must_plot = True if not success: # Note: the error message is a child of the settings dialog, so that # that dialog remains on top when the error message is closed error_message = QErrorMessage(self.settings_dialog) error_message.setWindowTitle("Input device error") error_message.showMessage("Impossible to use the selected input" " device, reverting to the previous one")
def onError(self, error): if error == QProcess.FailedToStart: msg = QCoreApplication.translate( "GdalTools", "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program." ) elif error == QProcess.Crashed: msg = QCoreApplication.translate( "GdalTools", "The process crashed some time after starting successfully.") else: msg = QCoreApplication.translate("GdalTools", "An unknown error occurred.") QErrorMessage(self).showMessage(msg) QApplication.processEvents() # give the user chance to see the message self.stop()
def __init__(self, parent, app): super(QWidget, self).__init__() self.app = app self.setupUi(self) self.error_msg = QErrorMessage() self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION) self.slider_frame_rate.valueChanged.connect(self.slider_frame_rate_changed) self.spinbox_frame_rate.valueChanged.connect(self.spinbox_frame_rate_changed) self.button_choose.pressed.connect(self.choose_pressed) self.button_show.pressed.connect(self.show_pressed) self.button_default.pressed.connect(self.default_pressed) self.update_frame_rate_timer = QTimer(self) self.update_frame_rate_timer.timeout.connect(self.update_frame_rate) self.default_pressed()
def onFinished(self, exitCode, status): if status == QProcess.CrashExit: self.stop() return if self.command.find("gdalinfo") != -1 and exitCode == 0: self.emit(SIGNAL("finished(bool)"), self.loadCheckBox.isChecked()) self.stop() return # show the error message if there's one, otherwise show the process output message msg = unicode(self.process.readAllStandardError()) if msg == '': outMessages = unicode( self.process.readAllStandardOutput()).splitlines() # make sure to not show the help for m in outMessages: m = string.strip(m) if m == '': continue # TODO fix this #if m.contains( QRegExp( "^(?:[Uu]sage:\\s)?" + QRegExp.escape(self.command) + "\\s" ) ): # if msg.isEmpty(): # msg = self.tr ( "Invalid parameters." ) # break #if m.contains( QRegExp( "0(?:\\.+[1-9]0{1,2})+" ) ): # continue if msg: msg += "\n" msg += m QErrorMessage(self).showMessage(msg.replace("\n", "<br>")) if exitCode == 0: self.emit(SIGNAL("finished(bool)"), self.loadCheckBox.isChecked()) self.stop()
def crear_y_seleccionar_archivo(self, nombre): # Quita la extension si llega a tenerla. nombre = nombre.replace('.py', '') nombre += ".py" nombre_de_archivo = nombre if self.ruta_del_archivo_actual: base_path = os.path.abspath(os.path.dirname(self.ruta_del_archivo_actual)) ruta = os.path.join(base_path, unicode(nombre_de_archivo)) else: ruta = unicode(nombre_de_archivo) if os.path.exists(ruta): self._tmp_dialog = QErrorMessage(self) self._tmp_dialog.showMessage("Ya existe un archivo con ese nombre") else: self._crear_archivo_nuevo_en(ruta) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos()
def loadParameterSet(self): s = QSettings() name = self.configCombo.currentText() s.beginGroup('ParameterSets') if not name in s.childGroups(): dlg = QErrorMessage(self) dlg.setWindowTitle('Error') dlg.showMessage('No saved parameters available for %s' % name) return s.beginGroup(name) for item in self.parameterItems: item.setValue(s.value(item.objectName(), item.value(), type=float)) self.adjustExcitationCb.setChecked(s.value('adjustExcitation', False, type=bool)) self.sensorNameLe.setText(s.value('sensorName', '', type=QString)) self.visaCombo.setCurrentIndex(self.visaCombo.findText(s.value('sr830Visa', 'GPIB0::12', type=QString))) self.autoRangingCb.setChecked(s.value('autoRanging', True, type=bool)) self.minSensitivityCombo.setCurrentCodeSilently(s.value('minSensitivity', 0, type=int)) s.endGroup() s.endGroup()
def __init__(self, *args): PluginBase.__init__(self, BrickDC, *args) self.setupUi(self) self.dc = self.device self.encoder_hide_all() self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(4, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.frequency_syncer = SliderSpinSyncer(self.frequency_slider, self.frequency_spin, self.frequency_changed) self.radio_mode_brake.toggled.connect(self.brake_value_changed) self.radio_mode_coast.toggled.connect(self.coast_value_changed) self.minimum_voltage_button.clicked.connect( self.minimum_voltage_button_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.emergency_signal = None self.under_signal = None self.current_velocity_signal = None self.velocity_reached_signal = None self.qem = QErrorMessage(self) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown) self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN, self.qtcb_emergency_shutdown.emit) self.qtcb_velocity_reached.connect(self.update_velocity) self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED, self.qtcb_velocity_reached.emit) self.cbe_current_velocity = CallbackEmulator( self.dc.get_current_velocity, self.update_velocity, self.increase_error_count) if self.firmware_version >= (1, 1, 3): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.dc.reset()) self.set_actions(reset)
class Blinkenlights(QApplication): HOST = "localhost" PORT = 4223 ipcon = None projects = [] active_project = None error_msg = None def __init__(self, args): super(QApplication, self).__init__(args) self.error_msg = QErrorMessage() self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION) signal.signal(signal.SIGINT, self.exit_demo) signal.signal(signal.SIGTERM, self.exit_demo) self.make_gui() self.connect() def exit_demo(self, signl=None, frme=None): try: self.ipcon.disconnect() self.timer.stop() self.tabs.destroy() except: pass sys.exit() def make_gui(self): self.main = MainWindow(self) self.main.setWindowIcon(QIcon(os.path.join(ProgramPath.program_path(), "demo-icon.png"))) self.tabs = QTabWidget() widget = QWidget() layout = QVBoxLayout() layout.addWidget(self.tabs) widget.setLayout(layout) self.main.setCentralWidget(widget) self.setup = SetupWidget(self.tabs, self) self.tetris = TetrisWidget(self.tabs, self) self.pong = PongWidget(self.tabs, self) self.fire = FireWidget(self.tabs, self) self.text = TextWidget(self.tabs, self) self.images = ImagesWidget(self.tabs, self) self.rainbow = RainbowWidget(self.tabs, self) self.projects.append(self.setup) self.projects.append(self.tetris) self.projects.append(self.pong) self.projects.append(self.fire) self.projects.append(self.text) self.projects.append(self.images) self.projects.append(self.rainbow) self.tabs.addTab(self.setup, "Setup") self.tabs.addTab(self.tetris, "Tetris") self.tabs.addTab(self.pong, "Pong") self.tabs.addTab(self.fire, "Fire") self.tabs.addTab(self.text, "Text") self.tabs.addTab(self.images, "Images") self.tabs.addTab(self.rainbow, "Rainbow") self.active_project = self.projects[0] self.tabs.currentChanged.connect(self.tab_changed_slot) self.main.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION) self.main.show() def connect(self): config.UID_LED_STRIP_BRICKLET = None self.setup.label_led_strip_found.setText('No') self.setup.label_led_strip_uid.setText('None') config.UID_MULTI_TOUCH_BRICKLET = None self.setup.label_multi_touch_found.setText('No') self.setup.label_multi_touch_uid.setText('None') config.UID_DUAL_BUTTON_BRICKLET = (None, None) self.setup.label_dual_button1_found.setText('No') self.setup.label_dual_button1_uid.setText('None') self.setup.label_dual_button2_found.setText('No') self.setup.label_dual_button2_uid.setText('None') config.UID_PIEZO_SPEAKER_BRICKLET = None self.setup.label_piezo_speaker_found.setText('No') self.setup.label_piezo_speaker_uid.setText('None') config.UID_SEGMENT_DISPLAY_4X7_BRICKLET = None self.setup.label_segment_display_found.setText('No') self.setup.label_segment_display_uid.setText('None') if self.ipcon != None: try: self.ipcon.disconnect() except: pass self.ipcon = IPConnection() host = self.setup.edit_host.text() port = self.setup.spinbox_port.value() try: self.ipcon.connect(host, port) except Error as e: self.error_msg.showMessage('Connection Error: ' + str(e.description) + "<br><br>Brickd installed and running?") return except socket.error as e: self.error_msg.showMessage('Socket error: ' + str(e) + "<br><br>Brickd installed and running?") return self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate) self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.cb_connected) # Wait for a second to give user visual feedback timer = QTimer(self) timer.setSingleShot(True) timer.timeout.connect(self.ipcon.enumerate) timer.start(250) def tab_changed_slot(self, tabIndex): self.active_project.stop() self.active_project = self.projects[tabIndex] self.active_project.start() def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \ enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE: if device_identifier == LEDStrip.DEVICE_IDENTIFIER: config.UID_LED_STRIP_BRICKLET = uid self.setup.label_led_strip_found.setText('Yes') self.setup.label_led_strip_uid.setText(uid) elif device_identifier == MultiTouch.DEVICE_IDENTIFIER: config.UID_MULTI_TOUCH_BRICKLET = uid self.setup.label_multi_touch_found.setText('Yes') self.setup.label_multi_touch_uid.setText(uid) elif device_identifier == DualButton.DEVICE_IDENTIFIER: if config.UID_DUAL_BUTTON_BRICKLET[0] == None: config.UID_DUAL_BUTTON_BRICKLET = (uid, None) self.setup.label_dual_button1_found.setText('Yes') self.setup.label_dual_button1_uid.setText(uid) else: config.UID_DUAL_BUTTON_BRICKLET = (config.UID_DUAL_BUTTON_BRICKLET[0], uid) self.setup.label_dual_button2_found.setText('Yes') self.setup.label_dual_button2_uid.setText(uid) elif device_identifier == PiezoSpeaker.DEVICE_IDENTIFIER: config.UID_PIEZO_SPEAKER_BRICKLET = uid self.setup.label_piezo_speaker_found.setText('Yes') self.setup.label_piezo_speaker_uid.setText(uid) elif device_identifier == SegmentDisplay4x7.DEVICE_IDENTIFIER: config.UID_SEGMENT_DISPLAY_4X7_BRICKLET = uid self.setup.label_segment_display_found.setText('Yes') self.setup.label_segment_display_uid.setText(uid) def cb_connected(self, connected_reason): if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT: while True: try: self.ipcon.enumerate() break except Error as e: self.error_msg.showMessage('Enumerate Error: ' + str(e.description)) time.sleep(1)
class ProjectXively(QWidget): qtcb_update_illuminance = pyqtSignal(float) qtcb_update_air_pressure = pyqtSignal(float) qtcb_update_temperature = pyqtSignal(float) qtcb_update_humidity = pyqtSignal(float) qtcb_button_pressed = pyqtSignal(int) lcdwidget = None xively_host = "api.xively.com" xively_agent = "Tinkerforge Starter Kit Weather Station Demo" xively_channel = "Enter Feed ID here" xively_api_key = "Enter API Key here" xively_items = {} xively_headers = None xively_params = "" xively_update_rate = 5 # in minutes text_agent = None text_channel = None text_api_key = None number_update_rate = None save_button = None xively_timer = None error_message = None label_upload_active = None last_upload = None def __init__(self, parent, app): super(QWidget, self).__init__() self.lcdwidget = LCDWidget(self, app) self.lcdwidget.hide() self.text_agent = QLineEdit(self) self.text_agent.setText(self.xively_agent) self.text_channel = QLineEdit(self) self.text_channel.setText(self.xively_channel) self.text_api_key = QLineEdit(self) self.text_api_key.setText(self.xively_api_key) self.number_update_rate = QSpinBox(self) self.number_update_rate.setRange(1, 1440) self.number_update_rate.setSuffix(' min') self.number_update_rate.setValue(self.xively_update_rate) layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout1.addStretch() layout1.addLayout(layout2) layout1.addStretch() layout2.addSpacerItem(QSpacerItem(LCDWidget.FIXED_WIDGTH, 0)) label = QLabel(self) label.setText("Project: <b>Connect to Xively</b>. This project uploads the measured values to Xively. Please find documentation how to configure it and program sources in Python <a href=\"http://www.tinkerforge.com/en/doc/Kits/WeatherStation/WeatherStation.html#connect-to-xively\">here</a>.<br>") label.setTextFormat(Qt.RichText) label.setTextInteractionFlags(Qt.TextBrowserInteraction) label.setOpenExternalLinks(True) label.setWordWrap(True) label.setAlignment(Qt.AlignJustify) layout2.addSpacing(10) layout2.addWidget(label) layout2.addSpacing(10) layout3a = QHBoxLayout() label = QLabel("Agent Description:") label.setMinimumWidth(150) layout3a.addWidget(label) layout3a.addWidget(self.text_agent, 1) layout2.addLayout(layout3a) layout2.addSpacing(10) layout3b = QHBoxLayout() label = QLabel("Feed:") label.setMinimumWidth(150) layout3b.addWidget(label) layout3b.addWidget(self.text_channel, 1) layout2.addLayout(layout3b) layout2.addSpacing(10) layout3c = QHBoxLayout() label = QLabel("API Key:") label.setMinimumWidth(150) layout3c.addWidget(label) layout3c.addWidget(self.text_api_key, 1) layout2.addLayout(layout3c) layout2.addSpacing(10) layout3d = QHBoxLayout() label = QLabel("Update Rate:") label.setMinimumWidth(150) layout3d.addWidget(label) layout3d.addWidget(self.number_update_rate, 1) layout2.addLayout(layout3d) layout2.addSpacing(10) self.label_upload_active = QLabel("Not Active", self) self.label_upload_active.setMinimumWidth(150) font = QFont() font.setPixelSize(20) self.label_upload_active.setFont(font) self.set_active_label(False) self.save_button = QPushButton("Save/Activate") layout4 = QHBoxLayout() layout4.addWidget(self.label_upload_active) layout4.addWidget(self.save_button, 1) layout2.addLayout(layout4) layout2.addStretch() self.setLayout(layout1) self.qtcb_update_illuminance.connect(self.update_illuminance_data_slot) self.qtcb_update_air_pressure.connect(self.update_air_pressure_data_slot) self.qtcb_update_temperature.connect(self.update_temperature_data_slot) self.qtcb_update_humidity.connect(self.update_humidity_data_slot) self.qtcb_button_pressed.connect(self.button_pressed_slot) self.save_button.clicked.connect(self.save_configuration) self.lcdwidget.clear(self) self.error_message = QErrorMessage(self) def set_active_label(self, value): palette = self.label_upload_active.palette() if value: palette.setColor(self.foregroundRole(), Qt.darkGreen) self.label_upload_active.setText("Active") else: palette.setColor(self.foregroundRole(), Qt.red) self.label_upload_active.setText("Not Active") self.label_upload_active.setPalette(palette) def save_configuration(self): try: self.xively_agent = str(self.text_agent.text()).decode('ascii') self.xively_channel = str(self.text_channel.text()).decode('ascii') self.xively_api_key = str(self.text_api_key.text()).decode('ascii') except: self.error_message.showMessage('Agent, Feed and API Key can only contain ASCII characters') return self.xively_update_rate = self.number_update_rate.value() self.xively_headers = { "Content-Type" : "application/x-www-form-urlencoded", "X-ApiKey" : self.xively_api_key, "User-Agent" : self.xively_agent, } self.xively_params = "/v2/feeds/" + self.xively_channel if self.xively_timer is None: self.xively_timer = QTimer(self) self.xively_timer.timeout.connect(self.update_xively) self.xively_timer.start(self.xively_update_rate*60*1000) self.set_active_label(True) self.update_xively() def write_lcd(self): if self.last_upload == None: tmp = "Last: Never" else: tmp = "Last: " + self.last_upload self.lcdwidget.write_line(0, 0, "Xively Upload", self) self.lcdwidget.write_line(2, 0, tmp, self) def update_xively(self): if len(self.xively_items) == 0: return stream_items = [] for identifier, value in self.xively_items.items(): stream_items.append({'id': identifier, 'current_value': value[0], 'min_value': value[1], 'max_value': value[2]}) data = {'version': '1.0.0', 'datastreams': stream_items} self.xively_items = {} body = json.dumps(data) try: http = httplib.HTTPSConnection(self.xively_host) http.request('PUT', self.xively_params, body, self.xively_headers) response = http.getresponse() http.close() if response.status != 200: self.error_message.showMessage('Could not upload to xively -> Response:' + str(response.status) + ': ' + response.reason + '. Check your configuration.') self.xively_timer.stop() self.xively_timer = None self.set_active_label(False) return except Exception as e: self.error_message.showMessage('HTTP error: ' + str(e)) self.xively_timer.stop() self.xively_timer = None self.set_active_label(False) return # set upload time if upload was a success self.last_upload = time.strftime("%H:%M:%S") def put(self, identifier, value): self.write_lcd() try: _, min_value, max_value = self.xively_items[identifier] if value < min_value: min_value = value if value > max_value: max_value = value self.xively_items[identifier] = (value, min_value, max_value) except: self.xively_items[identifier] = (value, value, value) def update_illuminance_data_slot(self, illuminance): self.put('AmbientLight', illuminance/10.0) def update_illuminance(self, illuminance): self.qtcb_update_illuminance.emit(illuminance) def update_humidity_data_slot(self, humidity): self.put('Humidity', humidity/10.0) def update_humidity(self, humidity): self.qtcb_update_humidity.emit(humidity) def update_air_pressure_data_slot(self, air_pressure): self.put('AirPressure', air_pressure/1000.0) def update_air_pressure(self, air_pressure): self.qtcb_update_air_pressure.emit(air_pressure) def update_temperature_data_slot(self, temperature): self.put('Temperature', temperature/100.0) def update_temperature(self, temperature): self.qtcb_update_temperature.emit(temperature) def button_pressed_slot(self, button): pass def button_pressed(self, button): self.qtcb_button_pressed.emit(button)
class DC(PluginBase, Ui_DC): qtcb_position_reached = pyqtSignal(int) qtcb_under_voltage = pyqtSignal(int) qtcb_emergency_shutdown = pyqtSignal() def __init__ (self, ipcon, uid): PluginBase.__init__(self, ipcon, uid) self.setupUi(self) self.dc = brick_dc.DC(self.uid) self.device = self.dc self.ipcon.add_device(self.dc) self.version = '.'.join(map(str, self.dc.get_version()[1])) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(4, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.velocity_slider.sliderReleased.connect(self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished) self.frequency_slider.sliderReleased.connect(self.frequency_slider_released) self.frequency_slider.valueChanged.connect(self.frequency_spin.setValue) self.frequency_spin.editingFinished.connect(self.frequency_spin_finished) self.radio_mode_brake.toggled.connect(self.brake_value_changed) self.radio_mode_coast.toggled.connect(self.coast_value_changed) self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed) self.full_brake_button.pressed.connect(self.full_brake_pressed) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.emergency_signal = None self.under_signal = None self.current_velocity_signal = None self.velocity_reached_signal = None self.qem = QErrorMessage(self) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown) self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN, self.qtcb_emergency_shutdown.emit) self.qtcb_position_reached.connect(self.update_velocity) self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED, self.qtcb_position_reached.emit) self.dc.register_callback(self.dc.CALLBACK_CURRENT_VELOCITY, self.qtcb_position_reached.emit) def start(self): self.update_timer.start(1000) try: self.dc.set_current_velocity_period(100) self.update_start() self.update_data() except ip_connection.Error: return def stop(self): self.update_timer.stop() try: self.dc.set_current_velocity_period(0) except ip_connection.Error: return @staticmethod def has_name(name): return 'DC Brick' in name def cb_emergency_shutdown(self): if not self.qem.isVisible(): self.qem.setWindowTitle("Emergency Shutdown") self.qem.showMessage("Emergency Shutdown: Short-Circuit or Over-Temperature") def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov/1000.0, 1) if not self.qem.isVisible(): self.qem.setWindowTitle("Under Voltage") self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str) def enable_state_changed(self, state): try: if state == Qt.Checked: self.dc.enable() elif state == Qt.Unchecked: self.dc.disable() except ip_connection.Error: return def brake_value_changed(self, checked): if checked: try: self.dc.set_drive_mode(0) except ip_connection.Error: return def coast_value_changed(self, checked): if checked: try: self.dc.set_drive_mode(1) except ip_connection.Error: return def full_brake_pressed(self): try: self.dc.full_brake() except ip_connection.Error: return def minimum_voltage_selected(self, value): try: self.dc.set_minimum_voltage(value) except ip_connection.Error: return def minimum_voltage_button_pressed(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(5000) qid.setIntMaximum(0xFFFF) qid.setIntStep(100) try: qid.setIntValue(self.dc.get_minimum_voltage()) except ip_connection.Error: return qid.intValueSelected.connect(self.minimum_voltage_selected) qid.setLabelText("Choose minimum motor voltage in mV.") qid.open() def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev/1000.0, 1) self.external_voltage_label.setText(ev_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv/1000.0, 1) self.minimum_voltage_label.setText(mv_str) def drive_mode_update(self, dm): if dm == 0: self.radio_mode_brake.setChecked(True) self.radio_mode_coast.setChecked(False) else: self.radio_mode_brake.setChecked(False) self.radio_mode_coast.setChecked(True) def current_consumption_update(self, cc): if cc >= 1000: cc_str = "%gA" % round(cc/1000.0, 1) else: cc_str = "%gmA" % cc self.current_label.setText(cc_str) def update_velocity(self, value): if value != self.speedometer.value(): self.speedometer.set_velocity(value) def update_start(self): try: dm = self.dc.get_drive_mode() self.drive_mode_update(dm) if not self.velocity_slider.isSliderDown(): velocity = self.dc.get_velocity() if velocity != self.velocity_slider.sliderPosition(): self.velocity_slider.setSliderPosition(velocity) self.velocity_spin.setValue(velocity) if not self.acceleration_slider.isSliderDown(): acceleration = self.dc.get_acceleration() if acceleration != self.acceleration_slider.sliderPosition(): self.acceleration_slider.setSliderPosition(acceleration) self.acceleration_spin.setValue(acceleration) if not self.frequency_slider.isSliderDown(): frequency = self.dc.get_pwm_frequency() if frequency != self.frequency_slider.sliderPosition(): self.frequency_slider.setSliderPosition(frequency) self.frequency_spin.setValue(frequency) enabled = self.dc.is_enabled() if enabled: self.enable_checkbox.setCheckState(Qt.Checked) else: self.enable_checkbox.setCheckState(Qt.Unchecked) except ip_connection.Error: return def update_data(self): try: sv = self.dc.get_stack_input_voltage() ev = self.dc.get_external_input_voltage() mv = self.dc.get_minimum_voltage() cc = self.dc.get_current_consumption() except ip_connection.Error: return self.stack_input_voltage_update(sv) self.external_input_voltage_update(ev) self.minimum_voltage_update(mv) self.current_consumption_update(cc) def acceleration_slider_released(self): value = self.acceleration_slider.value() self.acceleration_spin.setValue(value) try: self.dc.set_acceleration(value) except ip_connection.Error: return def acceleration_spin_finished(self): value = self.acceleration_spin.value() self.acceleration_slider.setValue(value) try: self.dc.set_acceleration(value) except ip_connection.Error: return def velocity_slider_released(self): value = self.velocity_slider.value() self.velocity_spin.setValue(value) try: self.dc.set_velocity(value) except ip_connection.Error: return def velocity_spin_finished(self): value = self.velocity_spin.value() self.velocity_slider.setValue(value) try: self.dc.set_velocity(value) except ip_connection.Error: return def frequency_slider_released(self): value = self.frequency_slider.value() self.frequency_spin.setValue(value) try: self.dc.set_pwm_frequency(value) except ip_connection.Error: return def frequency_spin_finished(self): value = self.frequency_spin.value() self.frequency_slider.setValue(value) try: self.dc.set_pwm_frequency(value) except ip_connection.Error: return
class Editor(editor_base.EditorBase): """Representa el editor de texto que aparece en el panel derecho. El editor soporta autocompletado de código y resaltado de sintáxis. """ # Señal es emitida cuando el Editor ejecuta codigo signal_ejecutando = QtCore.pyqtSignal() def __init__(self, main, interpreterLocals, consola_lanas, ventana_interprete): super(Editor, self).__init__() self.cantidad_ejecuciones = 0 self.consola_lanas = consola_lanas self.ventana_interprete = ventana_interprete self.ruta_del_archivo_actual = None self.interpreterLocals = interpreterLocals self.setLineWrapMode(QTextEdit.NoWrap) self._cambios_sin_guardar = False self.main = main self.nombre_de_archivo_sugerido = "" self.watcher = pilasengine.watcher.Watcher(None, self.cuando_cambia_archivo_de_forma_externa) def crear_archivo_inicial(self): dirpath = tempfile.mkdtemp() archivo_temporal = os.path.join(dirpath, "mi_juego.py") archivo = codecs.open(archivo_temporal, "w", 'utf-8') archivo.write(CODIGO_INICIAL) archivo.close() #print("Creando el archivo " + str(archivo_temporal)) self.abrir_archivo_del_proyecto(archivo_temporal) def es_archivo_iniciar_sin_guardar(self): return self.nombre_de_archivo_sugerido == "" def crear_y_seleccionar_archivo(self, nombre): # Quita la extension si llega a tenerla. nombre = nombre.replace('.py', '') nombre += ".py" nombre_de_archivo = nombre if self.ruta_del_archivo_actual: base_path = os.path.abspath(os.path.dirname(self.ruta_del_archivo_actual)) ruta = os.path.join(base_path, unicode(nombre_de_archivo)) else: ruta = unicode(nombre_de_archivo) if os.path.exists(ruta): self._tmp_dialog = QErrorMessage(self) self._tmp_dialog.showMessage("Ya existe un archivo con ese nombre") else: self._crear_archivo_nuevo_en(ruta) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() def _crear_archivo_nuevo_en(self, ruta): fo = open(ruta, "wb") fo.write("# contenido") fo.close() def obtener_archivos_del_proyecto(self): base_path = os.path.dirname(self.nombre_de_archivo_sugerido) listado = os.listdir(base_path) return [x for x in listado if x.endswith('.py')] def keyPressEvent(self, event): "Atiene el evento de pulsación de tecla." self._cambios_sin_guardar = True # Permite usar tab como seleccionador de la palabra actual # en el popup de autocompletado. if event.key() in [Qt.Key_Tab]: if self.completer and self.completer.popup().isVisible(): event.ignore() nuevo_evento = QKeyEvent(QKeyEvent.KeyPress, Qt.Key_Return, Qt.NoModifier) try: if self.autocomplete(nuevo_evento): return None except UnicodeEncodeError: pass return None if editor_base.EditorBase.keyPressEvent(self, event): return None # Elimina los pares de caracteres especiales si los encuentra if event.key() == Qt.Key_Backspace: self._eliminar_pares_de_caracteres() self._borrar_un_grupo_de_espacios(event) if self.autocomplete(event): return None if event.key() == Qt.Key_Return: cursor = self.textCursor() block = self.document().findBlockByNumber(cursor.blockNumber()) whitespace = re.match(r"(\s*)", unicode(block.text())).group(1) linea_anterior = str(block.text()[:]) cantidad_espacios = linea_anterior.count(' ') / 4 if linea_anterior[-1:] == ':': whitespace = ' ' * (cantidad_espacios + 1) else: whitespace = ' ' * (cantidad_espacios) QTextEdit.keyPressEvent(self, event) return self.insertPlainText(whitespace) return QTextEdit.keyPressEvent(self, event) def _borrar_un_grupo_de_espacios(self, event): cursor = self.textCursor() block = self.document().findBlockByNumber(cursor.blockNumber()) whitespace = re.match(r"(.*)", unicode(block.text())).group(1) if whitespace.endswith(' '): QTextEdit.keyPressEvent(self, event) QTextEdit.keyPressEvent(self, event) QTextEdit.keyPressEvent(self, event) def tiene_cambios_sin_guardar(self): return self._cambios_sin_guardar def _get_current_line(self): "Obtiene la linea en donde se encuentra el cursor." tc = self.textCursor() tc.select(QTextCursor.LineUnderCursor) return tc.selectedText() def _get_position_in_block(self): tc = self.textCursor() position = tc.positionInBlock() - 1 return position def cargar_contenido_desde_archivo(self, ruta): "Carga todo el contenido del archivo indicado por ruta." with codecs.open(unicode(ruta), 'r', 'utf-8') as archivo: contenido = archivo.read() self.setText(contenido) self.nombre_de_archivo_sugerido = ruta self._cambios_sin_guardar = False def abrir_dialogo_cargar_archivo(self): return QFileDialog.getOpenFileName(self, "Abrir Archivo", self.nombre_de_archivo_sugerido, "Archivos python (*.py)", options=QFileDialog.DontUseNativeDialog) def abrir_archivo_del_proyecto(self, nombre_de_archivo): if self.tiene_cambios_sin_guardar(): if self.mensaje_guardar_cambios_abrir(): if not self.guardar_contenido_con_dialogo(): return else: return if self.ruta_del_archivo_actual: base_path = os.path.dirname(self.ruta_del_archivo_actual) ruta = os.path.join(base_path, unicode(nombre_de_archivo)) else: ruta = unicode(nombre_de_archivo) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() def abrir_archivo_con_dialogo(self): if self.tiene_cambios_sin_guardar(): if self.mensaje_guardar_cambios_abrir(): if not self.guardar_contenido_con_dialogo(): return else: return ruta = self.abrir_dialogo_cargar_archivo() if ruta: ruta = unicode(ruta) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() def cuando_cambia_archivo_de_forma_externa(self): self.recargar_archivo_actual() def recargar_archivo_actual(self): if self.ruta_del_archivo_actual: self.cargar_contenido_desde_archivo(self.ruta_del_archivo_actual) self.ejecutar() def mensaje_guardar_cambios_abrir(self): """Realizar una consulta usando un cuadro de dialogo simple se utiliza cuando hay cambios sin guardar y se desea abrir un archivo. Retorna True si el usuario presiona el boton *Guardar*, Retorna False si el usuario presiona *No*.""" titulo = u"¿Deseas guardar el contenido antes de abrir un archivo?" mensaje = u"El contenido se perdera sino los guardas" mensaje = QMessageBox.question(self, titulo, mensaje, "Guardar", "No") return (not mensaje) def mensaje_guardar_cambios_salir(self): """Realizar una consulta usando un cuadro de dialogo simple se utiliza cuando hay cambios sin guardar y se desa salir del Editor. Retorna 0 si el usuario presiona el boton *Salir sin guardar*, Retorna 1 si el usuario presiona *Guardar* Retorna 2 si presiona *Cancelar*.""" titulo = u"¿Deseas guardar el contenido antes de salir?" mensaje = u"El contenido se perdera sino los guardas" return QMessageBox.question(self, titulo, mensaje, "Salir sin guardar", "Guardar", "Cancelar") def marcar_error_en_la_linea(self, numero, descripcion): hi_selection = QTextEdit.ExtraSelection() hi_selection.format.setBackground(QColor(255, 220, 220)) hi_selection.format.setProperty(QTextFormat.FullWidthSelection, QVariant(True)) hi_selection.cursor = self.textCursor() posicion_linea = self.document().findBlockByLineNumber(numero).position() hi_selection.cursor.setPosition(posicion_linea) hi_selection.cursor.clearSelection() self.setExtraSelections([hi_selection]) def guardar_contenido_con_dialogo(self): ruta = self.abrir_dialogo_guardar_archivo() if not ruta: return False ruta = unicode(ruta) if not ruta.endswith('.py'): ruta += '.py' if ruta: self.guardar_contenido_en_el_archivo(ruta) self._cambios_sin_guardar = False self.ruta_del_archivo_actual = ruta self.nombre_de_archivo_sugerido = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.cargar_contenido_desde_archivo(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() self.main.habilitar_boton_nuevo() return True def guardar_contenido_directamente(self): if self.nombre_de_archivo_sugerido: self.guardar_contenido_en_el_archivo(self.nombre_de_archivo_sugerido) self._cambios_sin_guardar = False self.main.actualizar_el_listado_de_archivos() self.prevenir_live_reload() else: self.guardar_contenido_con_dialogo() def prevenir_live_reload(self): self.watcher.prevenir_reinicio() def salir(self): """Retorna True si puede salir y False si no""" if self.tiene_cambios_sin_guardar(): mensaje = self.mensaje_guardar_cambios_salir() if mensaje == 1: self.guardar_contenido_con_dialogo() elif mensaje == 2: return False return True def obtener_contenido(self): return unicode(self.document().toPlainText()) def ejecutar(self): ruta_personalizada = os.path.dirname(self.ruta_del_archivo_actual) #print "ejecutando texto desde widget editor" texto = self.obtener_contenido() #texto = self.editor.obtener_texto_sanitizado(self) # elimina cabecera de encoding. contenido = re.sub('coding\s*:\s*', '', texto) contenido = contenido.replace('import pilasengine', '') contenido = contenido.replace('pilas = pilasengine.iniciar', 'pilas.reiniciar') for x in contenido.split('\n'): if "__file__" in x: contenido = contenido.replace(x, "# livecoding: " + x + "\n") sys.path.append(ruta_personalizada) self.interpreterLocals['sys'] = sys # Muchos códigos personalizados necesitan cargar imágenes o sonidos # desde el directorio que contiene al archivo. Para hacer esto posible, # se llama a la función "pilas.utils.agregar_ruta_personalizada" con el # path al directorio que representa el script. Así la función "obtener_ruta_al_recurso" # puede evaluar al directorio del script en busca de recursos también. if ruta_personalizada: ruta_personalizada = ruta_personalizada.replace('\\', '/') agregar_ruta_personalizada = 'pilas.utils.agregar_ruta_personalizada("%s")' %(ruta_personalizada) contenido = contenido.replace('pilas.reiniciar(', agregar_ruta_personalizada+'\n'+'pilas.reiniciar(') modulos_a_recargar = [x for x in self.interpreterLocals.values() if inspect.ismodule(x) and x.__name__ not in ['pilasengine', 'inspect'] and 'pilasengine.' not in x.__name__] for m in modulos_a_recargar: reload(m) self.cantidad_ejecuciones += 1 # Limpia la consola a partir de la primer ejecucion luego de iniciar. if self.cantidad_ejecuciones > 1: self.main.limpiar_interprete() try: exec(contenido, self.interpreterLocals) except Exception, e: self.consola_lanas.insertar_error_desde_exception(e) self.ventana_interprete.mostrar_el_interprete() #self.marcar_error_en_la_linea(10, "pepepe") self.signal_ejecutando.emit()
class Stepper(PluginBase, Ui_Stepper): qtcb_position_reached = pyqtSignal(int) qtcb_under_voltage = pyqtSignal(int) def __init__(self, *args): PluginBase.__init__(self, BrickStepper, *args) self.setupUi(self) self.stepper = self.device self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.decay_widget.hide() self.setting_sync_rect_checkbox = False self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider, self.deceleration_spin, self.deceleration_changed) self.decay_syncer = SliderSpinSyncer(self.decay_slider, self.decay_spin, self.decay_changed) self.enable_checkbox.toggled.connect(self.enable_toggled) self.forward_button.clicked.connect(self.forward_clicked) self.stop_button.clicked.connect(self.stop_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.backward_button.clicked.connect(self.backward_clicked) self.to_button.clicked.connect(self.to_button_clicked) self.steps_button.clicked.connect(self.steps_button_clicked) self.motor_current_button.clicked.connect( self.motor_current_button_clicked) self.minimum_motor_voltage_button.clicked.connect( self.minimum_motor_voltage_button_clicked) self.sync_rect_checkbox.toggled.connect(self.sync_rect_toggled) self.mode_dropbox.currentIndexChanged.connect(self.mode_changed) self.qtcb_position_reached.connect(self.cb_position_reached) self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0 if self.firmware_version >= (2, 3, 1): self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect( lambda checked: self.stepper.enable_status_led() if checked else self.stepper.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None if self.firmware_version >= (1, 1, 4): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.stepper.reset()) self.set_actions([(0, None, [reset])]) def start(self): if self.firmware_version >= (2, 3, 1): async_call(self.stepper.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count) self.update_timer.start(100) self.update_start() def stop(self): self.update_timer.stop() def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickStepper.DEVICE_IDENTIFIER def cb_position_reached(self, position): self.position_update(position) self.endis_all(True) def disable_list(self, button_list): for button in button_list: button.setEnabled(False) def endis_all(self, value): self.forward_button.setEnabled(value) self.stop_button.setEnabled(value) self.backward_button.setEnabled(value) self.to_button.setEnabled(value) self.steps_button.setEnabled(value) self.full_brake_button.setEnabled(value) def mode_changed(self, index): try: self.stepper.set_step_mode(1 << index) self.mod = 1 << index except ip_connection.Error: return def forward_clicked(self): try: self.stepper.drive_forward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def backward_clicked(self): try: self.stepper.drive_backward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def stop_clicked(self): try: self.stepper.stop() except ip_connection.Error: return self.endis_all(True) def full_brake_clicked(self): try: self.stepper.full_brake() except ip_connection.Error: return self.endis_all(True) def to_button_clicked(self): drive_to = self.to_spin.value() try: self.stepper.set_target_position(drive_to) except ip_connection.Error: return self.disable_list([ self.to_button, self.steps_button, self.forward_button, self.backward_button ]) def steps_button_clicked(self): drive_steps = self.steps_spin.value() try: self.stepper.set_steps(drive_steps) except ip_connection.Error: return self.disable_list([ self.to_button, self.steps_button, self.forward_button, self.backward_button ]) def motor_current_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(2500) qid.setIntStep(100) async_call(self.stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.motor_current_selected) qid.setLabelText("Choose motor current in mA.") # "<font color=red>Setting this too high can destroy your Motor.</font>") qid.open() def minimum_motor_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(40000) qid.setIntStep(100) async_call(self.stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_motor_voltage_selected) qid.setLabelText("Choose minimum motor voltage in mV.") qid.open() def motor_current_selected(self, value): try: self.stepper.set_motor_current(value) except ip_connection.Error: return def minimum_motor_voltage_selected(self, value): try: self.stepper.set_minimum_voltage(value) except ip_connection.Error: return def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov / 1000.0, 1) if not self.qem.isVisible(): self.qem.showMessage( "Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "Stepper_UnderVoltage") def enable_toggled(self, checked): try: if checked: if not self.stepper.is_enabled(): self.endis_all(True) self.stepper.enable() else: if self.stepper.is_enabled(): self.endis_all(False) self.stepper.disable() except ip_connection.Error: return def sync_rect_toggled(self, checked): if not self.setting_sync_rect_checkbox and checked: rc = QMessageBox.warning( get_main_window(), 'Synchronous Rectification', 'If you want to use high speeds (> 10000 steps/s) for a large stepper motor with a ' + 'large inductivity we strongly suggest that you do not enable synchronous rectification. ' + 'Otherwise the Brick may not be able to cope with the load and overheat.', QMessageBox.Ok | QMessageBox.Cancel) if rc != QMessageBox.Ok: self.sync_rect_checkbox.setChecked(False) return try: self.stepper.set_sync_rect(checked) except ip_connection.Error: return self.decay_widget.setVisible(checked) def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv / 1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev / 1000.0, 1) self.external_voltage_label.setText(ev_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv / 1000.0, 1) self.minimum_voltage_label.setText(mv_str) def maximum_current_update(self, cur): cur_str = "%gA" % round(cur / 1000.0, 1) self.maximum_current_label.setText(cur_str) def position_update(self, pos): pos_str = "%d" % pos self.position_label.setText(pos_str) def remaining_steps_update(self, ste): ste_str = "%d" % ste self.remaining_steps_label.setText(ste_str) def current_velocity_update(self, velocity): velocity_str = "%d" % velocity self.current_velocity_label.setText(velocity_str) self.speedometer.set_velocity(velocity) def mode_update(self, mod): if mod == 8: index = 3 elif mod == 4: index = 2 elif mod == 2: index = 1 else: index = 0 self.mode_dropbox.setCurrentIndex(index) def get_max_velocity_async(self, velocity): if not self.velocity_slider.isSliderDown(): if velocity != self.velocity_slider.sliderPosition(): self.velocity_slider.setSliderPosition(velocity) self.velocity_spin.setValue(velocity) def get_speed_ramping_async(self, ramp): acc, dec = ramp if not self.acceleration_slider.isSliderDown() and \ not self.deceleration_slider.isSliderDown(): if acc != self.acceleration_slider.sliderPosition(): self.acceleration_slider.setSliderPosition(acc) self.acceleration_spin.setValue(acc) if dec != self.deceleration_slider.sliderPosition(): self.deceleration_slider.setSliderPosition(dec) self.deceleration_spin.setValue(dec) def get_decay_async(self, decay): if not self.decay_slider.isSliderDown(): if decay != self.decay_slider.sliderPosition(): self.decay_slider.setSliderPosition(decay) self.decay_spin.setValue(decay) def is_enabled_async(self, enabled): if enabled: if not self.enable_checkbox.isChecked(): self.endis_all(True) self.enable_checkbox.setChecked(True) else: if self.enable_checkbox.isChecked(): self.endis_all(False) self.enable_checkbox.setChecked(False) def is_sync_rect_async(self, sync_rect): self.setting_sync_rect_checkbox = True self.sync_rect_checkbox.setChecked(sync_rect) self.setting_sync_rect_checkbox = False def update_start(self): async_call(self.stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count) async_call(self.stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count) async_call(self.stepper.get_decay, None, self.get_decay_async, self.increase_error_count) async_call(self.stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count) async_call(self.stepper.is_sync_rect, None, self.is_sync_rect_async, self.increase_error_count) def update_data(self): async_call(self.stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count) async_call(self.stepper.get_current_position, None, self.position_update, self.increase_error_count) async_call(self.stepper.get_current_velocity, None, self.current_velocity_update, self.increase_error_count) self.update_counter += 1 if self.update_counter % 10 == 0: async_call(self.stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count) async_call(self.stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count) async_call(self.stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count) async_call(self.stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count) async_call(self.stepper.get_step_mode, None, self.mode_update, self.increase_error_count) def velocity_changed(self, value): try: self.stepper.set_max_velocity(value) except ip_connection.Error: return def acceleration_changed(self, value): dec = self.deceleration_spin.value() try: self.stepper.set_speed_ramping(value, dec) except ip_connection.Error: return def deceleration_changed(self, value): acc = self.acceleration_slider.value() try: self.stepper.set_speed_ramping(acc, value) except ip_connection.Error: return def decay_changed(self, value): try: self.stepper.set_decay(value) except ip_connection.Error: return
def __init__(self, *args): PluginBase.__init__(self, BrickServo, *args) self.setupUi(self) self.servo = self.device self.position_list = [] self.velocity_list = [] self.acceleration_list = [] self.enable_list = [] self.up_cur = 0 self.up_siv = 0 self.up_eiv = 0 self.up_opv = 0 self.up_mv = 0 self.up_ena = [0] * 7 self.up_pos = [0] * 7 self.up_vel = [0] * 7 self.up_acc = [0] * 7 self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_apply) self.update_timer.setInterval(50) self.alive = True for i in range(1, 8): label = QLabel() label.setText('Off') self.enable_list.append(label) self.status_grid.addWidget(label, i, 1) for i in range(1, 8): pk = PositionKnob() self.position_list.append(pk) self.status_grid.addWidget(pk, i, 2) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.velocity_list.append(cb) self.status_grid.addWidget(cb, i, 3) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.acceleration_list.append(cb) self.status_grid.addWidget(cb, i, 4) self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.test_button.clicked.connect(self.test_button_clicked) self.output_voltage_button.clicked.connect( self.output_voltage_button_clicked) self.servo_dropbox.currentIndexChanged.connect( lambda x: self.update_servo_specific()) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.position_syncer = SliderSpinSyncer(self.position_slider, self.position_spin, self.position_changed) self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.period_syncer = SliderSpinSyncer(self.period_slider, self.period_spin, self.period_changed) self.pulse_width_min_spin.editingFinished.connect( self.pulse_width_spin_finished) self.pulse_width_max_spin.editingFinished.connect( self.pulse_width_spin_finished) self.degree_min_spin.editingFinished.connect(self.degree_spin_finished) self.degree_max_spin.editingFinished.connect(self.degree_spin_finished) self.minimum_voltage_button.clicked.connect( self.minimum_voltage_button_clicked) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) class WorkerThread(QThread): def __init__(self, parent=None, func=None): QThread.__init__(self, parent) self.func = func def run(self): self.func() self.test_event = Event() self.test_thread_object = WorkerThread(self, self.test_thread) self.update_event = Event() self.update_thread_object = WorkerThread(self, self.update_thread) self.update_thread_first_time = False self.update_done_event = Event() self.update_done_event.set() if self.firmware_version >= (2, 3, 1): self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect( lambda checked: self.servo.enable_status_led() if checked else self.servo.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None if self.firmware_version >= (1, 1, 3): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.servo.reset()) self.set_actions([(0, None, [reset])])
def __init__(self, navdb): super(Gui, self).__init__([]) self.acdata = ACDataEvent() self.navdb = navdb self.radarwidget = [] self.command_history = [] self.cmdargs = [] self.history_pos = 0 self.command_mem = '' self.command_line = '' self.prev_cmdline = '' self.simevent_target = 0 self.mousepos = (0, 0) self.prevmousepos = (0, 0) self.panzoomchanged = False # Register our custom pan/zoom event for etype in [PanZoomEventType, ACDataEventType, SimInfoEventType, StackTextEventType, ShowDialogEventType, DisplayFlagEventType, RouteDataEventType, DisplayShapeEventType]: reg_etype = QEvent.registerEventType(etype) if reg_etype != etype: print('Warning: Registered event type differs from requested type id (%d != %d)' % (reg_etype, etype)) self.splash = Splash() self.splash.show() self.splash.showMessage('Constructing main window') self.processEvents() # Install error message handler handler = QErrorMessage.qtHandler() handler.setWindowFlags(Qt.WindowStaysOnTopHint) # Check and set OpenGL capabilities if not QGLFormat.hasOpenGL(): raise RuntimeError('No OpenGL support detected for this system!') else: f = QGLFormat() f.setVersion(3, 3) f.setProfile(QGLFormat.CoreProfile) f.setDoubleBuffer(True) QGLFormat.setDefaultFormat(f) print('QGLWidget initialized for OpenGL version %d.%d' % (f.majorVersion(), f.minorVersion())) # Create the main window and related widgets self.radarwidget = RadarWidget(navdb) self.win = MainWindow(self, self.radarwidget) self.nd = ND(shareWidget=self.radarwidget) # Enable HiDPI support (Qt5 only) if QT_VERSION == 5: self.setAttribute(Qt.AA_UseHighDpiPixmaps) timer = QTimer(self) timer.timeout.connect(self.radarwidget.updateGL) timer.timeout.connect(self.nd.updateGL) timer.start(50) # Load geo data if False: pb = QProgressDialog('Binary buffer file not found, or file out of date: Constructing vertex buffers from geo data.', 'Cancel', 0, 100) pb.setWindowFlags(Qt.WindowStaysOnTopHint) pb.show() for i in range(101): pb.setValue(i) self.processEvents() QThread.msleep(100) pb.close()
class Stepper(PluginBase, Ui_Stepper): qtcb_position_reached = pyqtSignal(int) qtcb_under_voltage = pyqtSignal(int) def __init__(self, ipcon, uid, version): PluginBase.__init__(self, ipcon, uid, 'Stepper Brick', version) self.setupUi(self) self.stepper = BrickStepper(uid, ipcon) self.device = self.stepper self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(5, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.velocity_slider.sliderReleased.connect(self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished) self.deceleration_slider.sliderReleased.connect(self.deceleration_slider_released) self.deceleration_slider.valueChanged.connect(self.deceleration_spin.setValue) self.deceleration_spin.editingFinished.connect(self.deceleration_spin_finished) # self.decay_slider.sliderReleased.connect(self.decay_slider_released) # self.decay_slider.valueChanged.connect(self.decay_spin.setValue) # self.decay_spin.editingFinished.connect(self.decay_spin_finished) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.forward_button.pressed.connect(self.forward_pressed) self.stop_button.pressed.connect(self.stop_pressed) self.full_brake_button.pressed.connect(self.full_brake_pressed) self.backward_button.pressed.connect(self.backward_pressed) self.to_button.pressed.connect(self.to_button_pressed) self.steps_button.pressed.connect(self.steps_button_pressed) self.motor_current_button.pressed.connect(self.motor_current_button_pressed) self.minimum_motor_voltage_button.pressed.connect(self.minimum_motor_voltage_button_pressed) self.mode_dropbox.currentIndexChanged.connect(self.mode_changed) self.qtcb_position_reached.connect(self.cb_position_reached) self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.update_data_async_thread = None self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0 def start(self): self.update_timer.start(100) self.update_start() def stop(self): self.update_timer.stop() def has_reset_device(self): return self.version >= (1, 1, 4) def reset_device(self): if self.has_reset_device(): self.stepper.reset() def is_brick(self): return True def get_url_part(self): return 'stepper' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickStepper.DEVICE_IDENTIFIER def cb_position_reached(self, position): self.position_update(position) self.endis_all(True) def disable_list(self, button_list): for button in button_list: button.setEnabled(False) def endis_all(self, value): self.forward_button.setEnabled(value) self.stop_button.setEnabled(value) self.backward_button.setEnabled(value) self.to_button.setEnabled(value) self.steps_button.setEnabled(value) self.full_brake_button.setEnabled(value) def mode_changed(self, index): try: self.stepper.set_step_mode(1 << index) self.mod = 1 << index except ip_connection.Error: return def forward_pressed(self): try: self.stepper.drive_forward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def backward_pressed(self): try: self.stepper.drive_backward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def stop_pressed(self): try: self.stepper.stop() except ip_connection.Error: return self.endis_all(True) def full_brake_pressed(self): try: self.stepper.full_brake() except ip_connection.Error: return self.endis_all(True) def to_button_pressed(self): drive_to = self.to_spin.value() try: self.stepper.set_target_position(drive_to) except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button, self.forward_button, self.backward_button]) def steps_button_pressed(self): drive_steps = self.steps_spin.value() try: self.stepper.set_steps(drive_steps) except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button, self.forward_button, self.backward_button]) def motor_current_button_pressed(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(2500) qid.setIntStep(100) async_call(self.stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.motor_current_selected) qid.setLabelText("Choose motor current in mA.") # "<font color=red>Setting this too high can destroy your Motor.</font>") qid.open() def minimum_motor_voltage_button_pressed(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(40000) qid.setIntStep(100) async_call(self.stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_motor_voltage_selected) qid.setLabelText("Choose minimum motor voltage in mV.") qid.open() def motor_current_selected(self, value): try: self.stepper.set_motor_current(value) except ip_connection.Error: return def minimum_motor_voltage_selected(self, value): try: self.stepper.set_minimum_voltage(value) except ip_connection.Error: return def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov/1000.0, 1) if not self.qem.isVisible(): self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "Stepper_UnderVoltage") def enable_state_changed(self, state): try: if state == Qt.Checked: self.endis_all(True) self.stepper.enable() elif state == Qt.Unchecked: self.endis_all(False) self.stepper.disable() except ip_connection.Error: return def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev/1000.0, 1) self.external_voltage_label.setText(ev_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv/1000.0, 1) self.minimum_voltage_label.setText(mv_str) def maximum_current_update(self, cur): cur_str = "%gA" % round(cur/1000.0, 1) self.maximum_current_label.setText(cur_str) def position_update(self, pos): pos_str = "%d" % pos self.position_label.setText(pos_str) def remaining_steps_update(self, ste): ste_str = "%d" % ste self.remaining_steps_label.setText(ste_str) def mode_update(self, mod): if mod == 8: index = 3 elif mod == 4: index = 2 elif mod == 2: index = 1 else: index = 0 self.mode_dropbox.setCurrentIndex(index) def get_max_velocity_async(self, velocity): if not self.velocity_slider.isSliderDown(): if velocity != self.velocity_slider.sliderPosition(): self.velocity_slider.setSliderPosition(velocity) self.velocity_spin.setValue(velocity) def get_speed_ramping_async(self, ramp): acc, dec = ramp if not self.acceleration_slider.isSliderDown() and \ not self.deceleration_slider.isSliderDown(): if acc != self.acceleration_slider.sliderPosition(): self.acceleration_slider.setSliderPosition(acc) self.acceleration_spin.setValue(acc) if dec != self.deceleration_slider.sliderPosition(): self.deceleration_slider.setSliderPosition(dec) self.deceleration_spin.setValue(dec) def is_enabled_async(self, enabled): if enabled: if self.enable_checkbox.checkState() != Qt.Checked: self.endis_all(True) self.enable_checkbox.setCheckState(Qt.Checked) else: if self.enable_checkbox.checkState() != Qt.Unchecked: self.endis_all(False) self.enable_checkbox.setCheckState(Qt.Unchecked) def update_start(self): async_call(self.stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count) async_call(self.stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count) async_call(self.stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count) def update_data(self): async_call(self.stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count) async_call(self.stepper.get_current_position, None, self.position_update, self.increase_error_count) async_call(self.stepper.get_current_velocity, None, self.speedometer.set_velocity, self.increase_error_count) self.update_counter += 1 if self.update_counter % 10 == 0: async_call(self.stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count) async_call(self.stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count) async_call(self.stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count) async_call(self.stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count) async_call(self.stepper.get_step_mode, None, self.mode_update, self.increase_error_count) def velocity_slider_released(self): value = self.velocity_slider.value() self.velocity_spin.setValue(value) try: self.stepper.set_max_velocity(value) except ip_connection.Error: return def velocity_spin_finished(self): value = self.velocity_spin.value() self.velocity_slider.setValue(value) try: self.stepper.set_max_velocity(value) except ip_connection.Error: return def acceleration_slider_released(self): acc = self.acceleration_slider.value() dec = self.deceleration_slider.value() self.acceleration_spin.setValue(acc) try: self.stepper.set_speed_ramping(acc, dec) except ip_connection.Error: return def acceleration_spin_finished(self): acc = self.acceleration_spin.value() dec = self.deceleration_spin.value() self.acceleration_slider.setValue(acc) try: self.stepper.set_speed_ramping(acc, dec) except ip_connection.Error: return def deceleration_slider_released(self): acc = self.acceleration_slider.value() dec = self.deceleration_slider.value() self.deceleration_spin.setValue(dec) try: self.stepper.set_speed_ramping(acc, dec) except ip_connection.Error: return def deceleration_spin_finished(self): acc = self.acceleration_spin.value() dec = self.deceleration_spin.value() self.deceleration_slider.setValue(dec) try: self.stepper.set_speed_ramping(acc, dec) except ip_connection.Error: return
class SilentStepper(PluginBase, Ui_SilentStepper): qtcb_position_reached = pyqtSignal(int) qtcb_under_voltage = pyqtSignal(int) def __init__(self, *args): PluginBase.__init__(self, BrickSilentStepper, *args) self.setupUi(self) self.silent_stepper = self.device self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(5, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider, self.deceleration_spin, self.deceleration_changed) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.forward_button.clicked.connect(self.forward_clicked) self.stop_button.clicked.connect(self.stop_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.backward_button.clicked.connect(self.backward_clicked) self.to_button.clicked.connect(self.to_button_clicked) self.steps_button.clicked.connect(self.steps_button_clicked) self.motor_current_button.clicked.connect(self.motor_current_button_clicked) self.minimum_motor_voltage_button.clicked.connect(self.minimum_motor_voltage_button_clicked) self.qtcb_position_reached.connect(self.cb_position_reached) self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) # Step Configuration self.step_resolution_dropbox.currentIndexChanged.connect(self.step_configuration_changed) self.interpolate_checkbox.stateChanged.connect(self.step_configuration_changed) # Basic Configuration self.standstill_current_spin.valueChanged.connect(self.basic_configuration_changed) self.motor_run_current_spin.valueChanged.connect(self.basic_configuration_changed) self.standstill_delay_time_spin.valueChanged.connect(self.basic_configuration_changed) self.power_down_time_spin.valueChanged.connect(self.basic_configuration_changed) self.stealth_threshold_spin.valueChanged.connect(self.basic_configuration_changed) self.coolstep_threashold_spin.valueChanged.connect(self.basic_configuration_changed) self.classic_threshold_spin.valueChanged.connect(self.basic_configuration_changed) self.high_velocity_chopper_mode_checkbox.stateChanged.connect(self.basic_configuration_changed) # Spreadcycle Configuration self.slow_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.enable_random_slow_decay_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed) self.fast_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.hysteresis_start_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.hysteresis_end_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.sinewave_offset_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.chopper_mode_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed) self.comperator_blank_time_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed) self.fast_decay_without_comperator_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed) # Stealth Configuration self.enable_stealth_checkbox.stateChanged.connect(self.stealth_configuration_changed) self.amplitude_spin.valueChanged.connect(self.stealth_configuration_changed) self.gradient_spin.valueChanged.connect(self.stealth_configuration_changed) self.enable_autoscale_checkbox.stateChanged.connect(self.stealth_configuration_changed) self.force_symmetric_checkbox.stateChanged.connect(self.stealth_configuration_changed) self.freewheel_mode_combo.currentIndexChanged.connect(self.stealth_configuration_changed) # Coolstep Configuration self.minimum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed) self.maximum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed) self.current_up_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) self.current_down_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) self.minimum_current_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) self.stallguard_threshold_value_spin.valueChanged.connect(self.coolstep_configuration_changed) self.stallguard_mode_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) # Misc Configuration self.disable_short_to_ground_protection_checkbox.stateChanged.connect(self.misc_configuration_changed) self.synchronize_phase_frequency_spin.valueChanged.connect(self.misc_configuration_changed) self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0 reset = QAction('Reset', self) reset.triggered.connect(lambda: self.silent_stepper.reset()) self.set_actions(reset) def start(self): self.update_timer.start(100) self.update_start() def stop(self): self.update_timer.stop() def destroy(self): pass def get_url_part(self): return 'silent_stepper' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickSilentStepper.DEVICE_IDENTIFIER def cb_position_reached(self, position): self.position_update(position) self.endis_all(True) def disable_list(self, button_list): for button in button_list: button.setEnabled(False) def endis_all(self, value): self.forward_button.setEnabled(value) self.stop_button.setEnabled(value) self.backward_button.setEnabled(value) self.to_button.setEnabled(value) self.steps_button.setEnabled(value) self.full_brake_button.setEnabled(value) def step_configuration_changed(self, _): step_resolution = self.step_resolution_dropbox.currentIndex() interpolation = self.interpolate_checkbox.isChecked() try: self.silent_stepper.set_step_configuration(step_resolution, interpolation) except ip_connection.Error: return def basic_configuration_changed(self, _): standstill_current = self.standstill_current_spin.value() motor_run_current = self.motor_run_current_spin.value() standstill_delay_time = self.standstill_delay_time_spin.value() power_down_time = self.power_down_time_spin.value() stealth_threshold = self.stealth_threshold_spin.value() coolstep_threshold = self.coolstep_threashold_spin.value() classic_threshold = self.classic_threshold_spin.value() high_velocity_chopper_mode = self.high_velocity_chopper_mode_checkbox.isChecked() try: self.silent_stepper.set_basic_configuration(standstill_current, motor_run_current, standstill_delay_time, power_down_time, stealth_threshold, coolstep_threshold, classic_threshold, high_velocity_chopper_mode) except ip_connection.Error: return def spreadcycle_configuration_changed(self, _): slow_decay_duration = self.slow_decay_duration_spin.value() enable_random_slow_decay = self.enable_random_slow_decay_checkbox.isChecked() fast_decay_duration = self.fast_decay_duration_spin.value() hysteresis_start_value = self.hysteresis_start_value_spin.value() hysteresis_end_value = self.hysteresis_end_value_spin.value() sinewave_offset = self.sinewave_offset_spin.value() chopper_mode = self.chopper_mode_combo.currentIndex() comperator_blank_time = self.comperator_blank_time_combo.currentIndex() fast_decay_without_comperator = self.fast_decay_without_comperator_checkbox.isChecked() try: self.silent_stepper.set_spreadcycle_configuration(slow_decay_duration, enable_random_slow_decay, fast_decay_duration, hysteresis_start_value, hysteresis_end_value, sinewave_offset, chopper_mode, comperator_blank_time, fast_decay_without_comperator) except ip_connection.Error: return def stealth_configuration_changed(self, _): enable_stealth = self.enable_stealth_checkbox.isChecked() amplitude = self.amplitude_spin.value() gradient = self.gradient_spin.value() enable_autoscale = self.enable_autoscale_checkbox.isChecked() force_symmetric = self.force_symmetric_checkbox.isChecked() freewheel_mode = self.freewheel_mode_combo.currentIndex() try: self.silent_stepper.set_stealth_configuration(enable_stealth, amplitude, gradient, enable_autoscale, force_symmetric, freewheel_mode) except ip_connection.Error: return def coolstep_configuration_changed(self, _): minimum_stallguard_value = self.minimum_stallguard_value_spin.value() maximum_stallguard_value = self.maximum_stallguard_value_spin.value() current_up_step_width = self.current_up_step_width_combo.currentIndex() current_down_step_width = self.current_down_step_width_combo.currentIndex() minimum_current = self.minimum_current_combo.currentIndex() stallguard_threshold_value = self.stallguard_threshold_value_spin.value() stallguard_mode = self.stallguard_mode_combo.currentIndex() try: self.silent_stepper.set_coolstep_configuration(minimum_stallguard_value, maximum_stallguard_value, current_up_step_width, current_down_step_width, minimum_current, stallguard_threshold_value, stallguard_mode) except ip_connection.Error: return def misc_configuration_changed(self, _): disable_short_to_ground_protection = self.disable_short_to_ground_protection_checkbox.isChecked() synchronize_phase_frequency = self.synchronize_phase_frequency_spin.value() try: self.silent_stepper.set_misc_configuration(disable_short_to_ground_protection, synchronize_phase_frequency) except ip_connection.Error: return def forward_clicked(self): try: self.silent_stepper.drive_forward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def backward_clicked(self): try: self.silent_stepper.drive_backward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def stop_clicked(self): try: self.silent_stepper.stop() except ip_connection.Error: return self.endis_all(True) def full_brake_clicked(self): try: self.silent_stepper.full_brake() except ip_connection.Error: return self.endis_all(True) def to_button_clicked(self): drive_to = self.to_spin.value() try: self.silent_stepper.set_target_position(drive_to) except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button, self.forward_button, self.backward_button]) def steps_button_clicked(self): drive_steps = self.steps_spin.value() try: self.silent_stepper.set_steps(drive_steps) except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button, self.forward_button, self.backward_button]) def motor_current_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(2500) qid.setIntStep(100) async_call(self.silent_stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.motor_current_selected) qid.setLabelText("Choose motor current in mA.") qid.open() def minimum_motor_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(40000) qid.setIntStep(100) async_call(self.silent_stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_motor_voltage_selected) qid.setLabelText("Choose minimum motor voltage in mV.") qid.open() def motor_current_selected(self, value): try: self.silent_stepper.set_motor_current(value) except ip_connection.Error: return def minimum_motor_voltage_selected(self, value): try: self.silent_stepper.set_minimum_voltage(value) except ip_connection.Error: return def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov/1000.0, 1) if not self.qem.isVisible(): self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "SilentStepper_UnderVoltage") def enable_state_changed(self, state): try: if state == Qt.Checked: self.endis_all(True) self.silent_stepper.enable() elif state == Qt.Unchecked: self.endis_all(False) self.silent_stepper.disable() except ip_connection.Error: return def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev/1000.0, 1) self.external_voltage_label.setText(ev_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv/1000.0, 1) self.minimum_voltage_label.setText(mv_str) def maximum_current_update(self, cur): cur_str = "%gA" % round(cur/1000.0, 1) self.maximum_current_label.setText(cur_str) def position_update(self, pos): pos_str = "%d" % pos self.position_label.setText(pos_str) def remaining_steps_update(self, ste): ste_str = "%d" % ste self.remaining_steps_label.setText(ste_str) def driver_status_update(self, update): if update.open_load == 0: self.status_open_load.setText('No') elif update.open_load == 1: self.status_open_load.setText('Phase A') elif update.open_load == 2: self.status_open_load.setText('Phase B') elif update.open_load == 3: self.status_open_load.setText('Phase A and B') else: self.status_open_load.setText('Unkown') if update.short_to_ground == 0: self.status_short_to_ground.setText('No') elif update.short_to_ground == 1: self.status_short_to_ground.setText('Phase A') elif update.short_to_ground == 2: self.status_short_to_ground.setText('Phase B') elif update.short_to_ground == 3: self.status_short_to_ground.setText('Phase A and B') else: self.status_short_to_ground.setText('Unkown') if update.over_temperature == 0: self.status_over_temperature.setText('No') elif update.over_temperature == 1: self.status_over_temperature.setText('<font color=yellow>Warning</font>') elif update.over_temperature == 2: self.status_over_temperature.setText('<font color=red>Limit</font>') if update.motor_stalled: self.status_motor_stalled.setText('Yes') else: self.status_motor_stalled.setText('No') self.status_actual_motor_current.setText(str(update.actual_motor_current)) if update.full_step_active: self.status_full_step_active.setText('Yes') else: self.status_full_step_active.setText('No') self.status_stallguard_result.setText(str(update.stallguard_result)) self.status_stealth_voltage_amplitude.setText(str(update.stealth_voltage_amplitude)) def get_max_velocity_async(self, velocity): if not self.velocity_slider.isSliderDown(): if velocity != self.velocity_slider.sliderPosition(): self.velocity_slider.setSliderPosition(velocity) self.velocity_spin.setValue(velocity) def get_speed_ramping_async(self, ramp): acc, dec = ramp if not self.acceleration_slider.isSliderDown() and \ not self.deceleration_slider.isSliderDown(): if acc != self.acceleration_slider.sliderPosition(): self.acceleration_slider.setSliderPosition(acc) self.acceleration_spin.setValue(acc) if dec != self.deceleration_slider.sliderPosition(): self.deceleration_slider.setSliderPosition(dec) self.deceleration_spin.setValue(dec) def is_enabled_async(self, enabled): if enabled: if not self.enable_checkbox.isChecked(): self.endis_all(True) self.enable_checkbox.blockSignals(True) self.enable_checkbox.setChecked(True) self.enable_checkbox.blockSignals(False) else: if self.enable_checkbox.isChecked(): self.endis_all(False) self.enable_checkbox.blockSignals(True) self.enable_checkbox.setChecked(False) self.enable_checkbox.blockSignals(False) def get_step_configuration_async(self, conf): self.step_resolution_dropbox.blockSignals(True) self.step_resolution_dropbox.setCurrentIndex(conf.step_resolution) self.step_resolution_dropbox.blockSignals(False) self.interpolate_checkbox.blockSignals(True) self.interpolate_checkbox.setChecked(conf.interpolation) self.interpolate_checkbox.blockSignals(False) def get_basic_configuration_async(self, conf): self.standstill_current_spin.blockSignals(True) self.standstill_current_spin.setValue(conf.standstill_current) self.standstill_current_spin.blockSignals(False) self.motor_run_current_spin.blockSignals(True) self.motor_run_current_spin.setValue(conf.motor_run_current) self.motor_run_current_spin.blockSignals(False) self.standstill_delay_time_spin.blockSignals(True) self.standstill_delay_time_spin.setValue(conf.standstill_delay_time) self.standstill_delay_time_spin.blockSignals(False) self.power_down_time_spin.blockSignals(True) self.power_down_time_spin.setValue(conf.power_down_time) self.power_down_time_spin.blockSignals(False) self.stealth_threshold_spin.blockSignals(True) self.stealth_threshold_spin.setValue(conf.stealth_threshold) self.stealth_threshold_spin.blockSignals(False) self.coolstep_threashold_spin.blockSignals(True) self.coolstep_threashold_spin.setValue(conf.coolstep_threshold) self.coolstep_threashold_spin.blockSignals(False) self.classic_threshold_spin.blockSignals(True) self.classic_threshold_spin.setValue(conf.classic_threshold) self.classic_threshold_spin.blockSignals(False) self.high_velocity_chopper_mode_checkbox.blockSignals(True) self.high_velocity_chopper_mode_checkbox.setChecked(conf.high_velocity_chopper_mode) self.high_velocity_chopper_mode_checkbox.blockSignals(False) def get_spreadcycle_configuration_async(self, conf): self.slow_decay_duration_spin.blockSignals(True) self.slow_decay_duration_spin.setValue(conf.slow_decay_duration) self.slow_decay_duration_spin.blockSignals(False) self.enable_random_slow_decay_checkbox.blockSignals(True) self.enable_random_slow_decay_checkbox.setChecked(conf.enable_random_slow_decay) self.enable_random_slow_decay_checkbox.blockSignals(False) self.fast_decay_duration_spin.blockSignals(True) self.fast_decay_duration_spin.setValue(conf.fast_decay_duration) self.fast_decay_duration_spin.blockSignals(False) self.hysteresis_start_value_spin.blockSignals(True) self.hysteresis_start_value_spin.setValue(conf.hysteresis_start_value) self.hysteresis_start_value_spin.blockSignals(False) self.hysteresis_end_value_spin.blockSignals(True) self.hysteresis_end_value_spin.setValue(conf.hysteresis_end_value) self.hysteresis_end_value_spin.blockSignals(False) self.sinewave_offset_spin.blockSignals(True) self.sinewave_offset_spin.setValue(conf.sinewave_offset) self.sinewave_offset_spin.blockSignals(False) self.chopper_mode_combo.blockSignals(True) self.chopper_mode_combo.setCurrentIndex(conf.chopper_mode) self.chopper_mode_combo.blockSignals(False) self.standstill_current_spin.blockSignals(True) self.comperator_blank_time_combo.setCurrentIndex(conf.comperator_blank_time) self.standstill_current_spin.blockSignals(False) self.fast_decay_without_comperator_checkbox.blockSignals(True) self.fast_decay_without_comperator_checkbox.setChecked(conf.fast_decay_without_comperator) self.fast_decay_without_comperator_checkbox.blockSignals(False) def get_stealth_configuration_async(self, conf): self.enable_stealth_checkbox.blockSignals(True) self.enable_stealth_checkbox.setChecked(conf.enable_stealth) self.enable_stealth_checkbox.blockSignals(False) self.amplitude_spin.blockSignals(True) self.amplitude_spin.setValue(conf.amplitude) self.amplitude_spin.blockSignals(False) self.gradient_spin.blockSignals(True) self.gradient_spin.setValue(conf.gradient) self.gradient_spin.blockSignals(False) self.enable_autoscale_checkbox.blockSignals(True) self.enable_autoscale_checkbox.setChecked(conf.enable_autoscale) self.enable_autoscale_checkbox.blockSignals(False) self.force_symmetric_checkbox.blockSignals(True) self.force_symmetric_checkbox.setChecked(conf.force_symmetric) self.force_symmetric_checkbox.blockSignals(False) self.freewheel_mode_combo.blockSignals(True) self.freewheel_mode_combo.setCurrentIndex(conf.freewheel_mode) self.freewheel_mode_combo.blockSignals(False) def get_coolstep_configuration_async(self, conf): self.minimum_stallguard_value_spin.blockSignals(True) self.minimum_stallguard_value_spin.setValue(conf.minimum_stallguard_value) self.minimum_stallguard_value_spin.blockSignals(False) self.maximum_stallguard_value_spin.blockSignals(True) self.maximum_stallguard_value_spin.setValue(conf.maximum_stallguard_value) self.maximum_stallguard_value_spin.blockSignals(False) self.current_up_step_width_combo.blockSignals(True) self.current_up_step_width_combo.setCurrentIndex(conf.current_up_step_width) self.current_up_step_width_combo.blockSignals(False) self.current_down_step_width_combo.blockSignals(True) self.current_down_step_width_combo.setCurrentIndex(conf.current_down_step_width) self.current_down_step_width_combo.blockSignals(False) self.minimum_current_combo.blockSignals(True) self.minimum_current_combo.setCurrentIndex(conf.minimum_current) self.minimum_current_combo.blockSignals(False) self.stallguard_threshold_value_spin.blockSignals(True) self.stallguard_threshold_value_spin.setValue(conf.stallguard_threshold_value) self.stallguard_threshold_value_spin.blockSignals(False) self.stallguard_mode_combo.blockSignals(True) self.stallguard_mode_combo.setCurrentIndex(conf.stallguard_mode) self.stallguard_mode_combo.blockSignals(False) def get_misc_configuration_async(self, conf): self.disable_short_to_ground_protection_checkbox.blockSignals(True) self.disable_short_to_ground_protection_checkbox.setChecked(conf.disable_short_to_ground_protection) self.disable_short_to_ground_protection_checkbox.blockSignals(False) self.synchronize_phase_frequency_spin.blockSignals(True) self.synchronize_phase_frequency_spin.setValue(conf.synchronize_phase_frequency) self.synchronize_phase_frequency_spin.blockSignals(False) def update_start(self): async_call(self.silent_stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count) async_call(self.silent_stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count) async_call(self.silent_stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count) async_call(self.silent_stepper.get_step_configuration, None, self.get_step_configuration_async, self.increase_error_count) async_call(self.silent_stepper.get_basic_configuration, None, self.get_basic_configuration_async, self.increase_error_count) async_call(self.silent_stepper.get_spreadcycle_configuration, None, self.get_spreadcycle_configuration_async, self.increase_error_count) async_call(self.silent_stepper.get_stealth_configuration, None, self.get_stealth_configuration_async, self.increase_error_count) async_call(self.silent_stepper.get_coolstep_configuration, None, self.get_coolstep_configuration_async, self.increase_error_count) async_call(self.silent_stepper.get_misc_configuration, None, self.get_misc_configuration_async, self.increase_error_count) def update_data(self): async_call(self.silent_stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count) async_call(self.silent_stepper.get_current_position, None, self.position_update, self.increase_error_count) async_call(self.silent_stepper.get_current_velocity, None, self.speedometer.set_velocity, self.increase_error_count) self.update_counter += 1 if self.update_counter % 10 == 0: async_call(self.silent_stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count) async_call(self.silent_stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count) async_call(self.silent_stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count) async_call(self.silent_stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count) async_call(self.silent_stepper.get_driver_status, None, self.driver_status_update, self.increase_error_count) def velocity_changed(self, value): try: self.silent_stepper.set_max_velocity(value) except ip_connection.Error: return def acceleration_changed(self, value): dec = self.deceleration_spin.value() try: self.silent_stepper.set_speed_ramping(value, dec) except ip_connection.Error: return def deceleration_changed(self, value): acc = self.acceleration_slider.value() try: self.silent_stepper.set_speed_ramping(acc, value) except ip_connection.Error: return
def main(): """ Main entry point into the application. """ global args, mainWindow, splash, restartArgs sys.excepthook = excepthook options = [\ ("--config=configDir", "use the given directory as the one containing the config files"), ("--debug", "activate debugging output to the console"), ("--nosplash", "don't show the splash screen"), ("--noopen", "don't open anything at startup except that given in command"), ("--nokde" , "don't use KDE widgets"), ("--plugin=plugin-file", "load the given plugin file (plugin development)"), ("--start-session", "load the global session file"), ("--", "indicate that there are options for the program to be debugged"), ("", "(everything after that is considered arguments for this program)") ] kqOptions = [\ ("config \\", "use the given directory as the one containing the config files"), ("debug", "activate debugging output to the console"), ("nosplash", "don't show the splash screen"), ("noopen", "don't open anything at startup except that given in command"), ("nokde" , "don't use KDE widgets"), ("plugin \\", "load the given plugin file (plugin development)"), ("start-session", "load the global session file"), ("!+file", "") ] appinfo = Startup.makeAppInfo(sys.argv, "Eric4", "[project | files... [--] [debug-options]]", "A Python IDE", options) ddindex = Startup.handleArgs(sys.argv, appinfo) if not Utilities.checkBlacklistedVersions(): sys.exit(100) app = KQApplication(sys.argv, kqOptions) if Preferences.getUI("SingleApplicationMode"): handleSingleApplication(ddindex) # set the library paths for plugins Startup.setLibraryPaths() # set the search path for icons Startup.initializeResourceSearchPath() # generate and show a splash window, if not suppressed if "--nosplash" in sys.argv and sys.argv.index("--nosplash") < ddindex: del sys.argv[sys.argv.index("--nosplash")] splash = NoneSplashScreen() elif not Preferences.getUI("ShowSplash"): splash = NoneSplashScreen() else: splash = SplashScreen() # modify the executable search path for the PyQt4 installer if Utilities.isWindowsPlatform(): pyqtDataDir = Utilities.getPyQt4ModulesDirectory() if os.path.exists(os.path.join(pyqtDataDir, "bin")): path = os.path.join(pyqtDataDir, "bin") + os.pathsep + os.environ["PATH"] else: path = pyqtDataDir + os.pathsep + os.environ["PATH"] os.environ["PATH"] = path pluginFile = None noopen = False if "--noopen" in sys.argv and sys.argv.index("--noopen") < ddindex: del sys.argv[sys.argv.index("--noopen")] noopen = True for arg in sys.argv: if arg.startswith("--plugin=") and sys.argv.index(arg) < ddindex: # extract the plugin development option pluginFile = arg.replace("--plugin=", "").replace('"', "") sys.argv.remove(arg) pluginFile = os.path.expanduser(pluginFile) pluginFile = Utilities.normabspath(pluginFile) break # is there a set of filenames or options on the command line, # if so, pass them to the UI if len(sys.argv) > 1: args = sys.argv[1:] # Set the applications string encoding try: sys.setappdefaultencoding(str(Preferences.getSystem("StringEncoding"))) except AttributeError: pass # get the Qt4 translations directory qt4TransDir = Preferences.getQt4TranslationsDir() if not qt4TransDir: qt4TransDir = QLibraryInfo.location(QLibraryInfo.TranslationsPath) # Load translation files and install them loc = Startup.loadTranslators(qt4TransDir, app, ("qscintilla",)) QTextCodec.setCodecForCStrings(QTextCodec.codecForName(\ str(Preferences.getSystem("StringEncoding")))) splash.showMessage(QApplication.translate("eric4", "Importing packages...")) # We can only import these after creating the KQApplication because they # make Qt calls that need the KQApplication to exist. from UI.UserInterface import UserInterface splash.showMessage(QApplication.translate("eric4", "Generating Main Window...")) try: mainWindow = UserInterface(app, loc, splash, pluginFile, noopen, restartArgs) app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) mainWindow.show() QTimer.singleShot(0, uiStartUp) # generate a graphical error handler eMsg = QErrorMessage.qtHandler() eMsg.setMinimumSize(600, 400) # start the event loop res = app.exec_() logging.debug("Shutting down, result %d" % res) logging.shutdown() sys.exit(res) except Exception, err: raise err
class ImagesWidget(QWidget, Ui_Images): images = None def __init__(self, parent, app): super(QWidget, self).__init__() self.app = app self.setupUi(self) self.error_msg = QErrorMessage() self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION) self.slider_frame_rate.valueChanged.connect(self.slider_frame_rate_changed) self.spinbox_frame_rate.valueChanged.connect(self.spinbox_frame_rate_changed) self.button_choose.pressed.connect(self.choose_pressed) self.button_show.pressed.connect(self.show_pressed) self.button_default.pressed.connect(self.default_pressed) self.update_frame_rate_timer = QTimer(self) self.update_frame_rate_timer.timeout.connect(self.update_frame_rate) self.default_pressed() def start(self): self.images = Images(self.app.ipcon) self.update_frame_rate() self.images.frame_rendered(0) def stop(self): if self.images: self.images.stop_rendering() self.images = None def spinbox_frame_rate_changed(self, frame_rate): self.slider_frame_rate.setValue(frame_rate) self.update_frame_rate_timer.start(100) def slider_frame_rate_changed(self, frame_rate): self.spinbox_frame_rate.setValue(frame_rate) def show_pressed(self): if self.images: files = unicode(self.text_edit_files.toPlainText()).strip() if len(files) > 0: new_images = files.split('\n') try: self.images.set_new_images(new_images) except Exception as e: self.error_msg.showMessage(str(e)) self.images.frame_prepare_next() self.images.frame_rendered(0) def choose_pressed(self): for filename in QFileDialog.getOpenFileNames(self, 'Choose Images', QDir.homePath()): self.text_edit_files.append(filename) def default_pressed(self): self.spinbox_frame_rate.setValue(1) def update_frame_rate(self): self.update_frame_rate_timer.stop() config.IMAGES_FRAME_RATE = self.spinbox_frame_rate.value() if self.images: self.images.update_frame_rate()
def __init__(self, *args): PluginBase.__init__(self, BrickSilentStepper, *args) self.setupUi(self) self.silent_stepper = self.device self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(5, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider, self.deceleration_spin, self.deceleration_changed) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.forward_button.clicked.connect(self.forward_clicked) self.stop_button.clicked.connect(self.stop_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.backward_button.clicked.connect(self.backward_clicked) self.to_button.clicked.connect(self.to_button_clicked) self.steps_button.clicked.connect(self.steps_button_clicked) self.motor_current_button.clicked.connect(self.motor_current_button_clicked) self.minimum_motor_voltage_button.clicked.connect(self.minimum_motor_voltage_button_clicked) self.qtcb_position_reached.connect(self.cb_position_reached) self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) # Step Configuration self.step_resolution_dropbox.currentIndexChanged.connect(self.step_configuration_changed) self.interpolate_checkbox.stateChanged.connect(self.step_configuration_changed) # Basic Configuration self.standstill_current_spin.valueChanged.connect(self.basic_configuration_changed) self.motor_run_current_spin.valueChanged.connect(self.basic_configuration_changed) self.standstill_delay_time_spin.valueChanged.connect(self.basic_configuration_changed) self.power_down_time_spin.valueChanged.connect(self.basic_configuration_changed) self.stealth_threshold_spin.valueChanged.connect(self.basic_configuration_changed) self.coolstep_threashold_spin.valueChanged.connect(self.basic_configuration_changed) self.classic_threshold_spin.valueChanged.connect(self.basic_configuration_changed) self.high_velocity_chopper_mode_checkbox.stateChanged.connect(self.basic_configuration_changed) # Spreadcycle Configuration self.slow_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.enable_random_slow_decay_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed) self.fast_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.hysteresis_start_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.hysteresis_end_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.sinewave_offset_spin.valueChanged.connect(self.spreadcycle_configuration_changed) self.chopper_mode_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed) self.comperator_blank_time_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed) self.fast_decay_without_comperator_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed) # Stealth Configuration self.enable_stealth_checkbox.stateChanged.connect(self.stealth_configuration_changed) self.amplitude_spin.valueChanged.connect(self.stealth_configuration_changed) self.gradient_spin.valueChanged.connect(self.stealth_configuration_changed) self.enable_autoscale_checkbox.stateChanged.connect(self.stealth_configuration_changed) self.force_symmetric_checkbox.stateChanged.connect(self.stealth_configuration_changed) self.freewheel_mode_combo.currentIndexChanged.connect(self.stealth_configuration_changed) # Coolstep Configuration self.minimum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed) self.maximum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed) self.current_up_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) self.current_down_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) self.minimum_current_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) self.stallguard_threshold_value_spin.valueChanged.connect(self.coolstep_configuration_changed) self.stallguard_mode_combo.currentIndexChanged.connect(self.coolstep_configuration_changed) # Misc Configuration self.disable_short_to_ground_protection_checkbox.stateChanged.connect(self.misc_configuration_changed) self.synchronize_phase_frequency_spin.valueChanged.connect(self.misc_configuration_changed) self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0 reset = QAction('Reset', self) reset.triggered.connect(lambda: self.silent_stepper.reset()) self.set_actions(reset)
class WeatherStation(QApplication): HOST = "localhost" PORT = 4223 ipcon = None lcd = None al = None al_v2 = None hum = None baro = None projects = [] active_project = None error_msg = None def __init__(self, args): super(QApplication, self).__init__(args) self.error_msg = QErrorMessage() self.ipcon = IPConnection() signal.signal(signal.SIGINT, self.exit_demo) signal.signal(signal.SIGTERM, self.exit_demo) timer = QTimer(self) timer.setSingleShot(True) timer.timeout.connect(self.connect) timer.start(1) self.lcd_timer = QTimer(self) self.lcd_timer.timeout.connect(self.mute_lcd) self.lcd_timer.start(10000) def exit_demo(self, signl=None, frme=None): try: self.ipcon.disconnect() self.timer.stop() self.tabs.destroy() except: pass sys.exit() def open_gui(self): self.main = MainWindow(self) self.main.setFixedSize(930, 530) self.main.setWindowIcon( QIcon(load_pixmap('starter_kit_weather_station_demo-icon.png'))) self.tabs = QTabWidget() widget = QWidget() layout = QVBoxLayout() layout.addWidget(self.tabs) widget.setLayout(layout) self.main.setCentralWidget(widget) self.projects.append(ProjectEnvDisplay(self.tabs, self)) self.projects.append(ProjectStatistics(self.tabs, self)) self.projects.append(ProjectXively(self.tabs, self)) self.tabs.addTab(self.projects[0], "Display Environment Measurements") self.tabs.addTab(self.projects[1], "Show Statistics with Button Control") self.tabs.addTab(self.projects[2], "Connect to Xively") self.active_project = self.projects[0] self.tabs.currentChanged.connect(self.tabChangedSlot) self.tabs.setCurrentIndex(1) self.main.setWindowTitle("Starter Kit: Weather Station Demo " + DEMO_VERSION) self.main.show() def connect(self): try: self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT) except Error as e: self.error_msg.showMessage('Connection Error: ' + str(e.description) + "\nBrickd installed and running?") return except socket.error as e: self.error_msg.showMessage('Socket error: ' + str(e) + "\nBrickd installed and running?") return self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate) self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.cb_connected) try: self.ipcon.enumerate() except Error as e: self.error_msg.showMessage('Enumerate Error: ' + str(e.description)) return self.open_gui() def tabChangedSlot(self, tabIndex): if self.lcd is not None: self.lcd.clear_display() self.active_project = self.projects[tabIndex] def cb_illuminance(self, illuminance): for p in self.projects: p.update_illuminance(illuminance / 10.0) def cb_illuminance_v2(self, illuminance): for p in self.projects: p.update_illuminance(illuminance / 100.0) def cb_humidity(self, humidity): for p in self.projects: p.update_humidity(humidity / 10.0) def cb_air_pressure(self, air_pressure): for p in self.projects: p.update_air_pressure(air_pressure / 1000.0) try: temperature = self.baro.get_chip_temperature() except Error as e: print('Could not get temperature: ' + str(e.description)) return for p in self.projects: p.update_temperature(temperature / 100.0) def configure_custom_chars(self): c = [[0x00 for x in range(8)] for y in range(8)] c[0] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff] c[1] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff] c[2] = [0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff] c[3] = [0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff] c[4] = [0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff] c[5] = [0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] c[6] = [0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] c[7] = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] for i in range(len(c)): self.lcd.set_custom_character(i, c[i]) def cb_button_pressed(self, button): if self.lcd.is_backlight_on(): for p in self.projects: p.button_pressed(button) else: self.lcd.backlight_on() self.lcd_timer.start() def mute_lcd(self): self.lcd.backlight_off() def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \ enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE: if device_identifier == LCD20x4.DEVICE_IDENTIFIER: try: self.lcd = LCD20x4(uid, self.ipcon) self.lcd.clear_display() self.lcd.backlight_on() self.lcd.register_callback( self.lcd.CALLBACK_BUTTON_PRESSED, self.cb_button_pressed) self.configure_custom_chars() except Error as e: self.error_msg.showMessage('LCD 20x4 init failed: ' + str(e.description)) self.lcd = None elif device_identifier == AmbientLight.DEVICE_IDENTIFIER: try: self.al = AmbientLight(uid, self.ipcon) self.al.set_illuminance_callback_period(1000) self.al.register_callback(self.al.CALLBACK_ILLUMINANCE, self.cb_illuminance) except Error as e: self.error_msg.showMessage('Ambient Light init failed: ' + str(e.description)) self.al = None elif device_identifier == AmbientLightV2.DEVICE_IDENTIFIER: try: self.al_v2 = AmbientLightV2(uid, self.ipcon) self.al_v2.set_configuration( AmbientLightV2.ILLUMINANCE_RANGE_64000LUX, AmbientLightV2.INTEGRATION_TIME_200MS) self.al_v2.set_illuminance_callback_period(1000) self.al_v2.register_callback( self.al_v2.CALLBACK_ILLUMINANCE, self.cb_illuminance_v2) except Error as e: self.error_msg.showMessage( 'Ambient Light 2.0 init failed: ' + str(e.description)) self.al = None elif device_identifier == Humidity.DEVICE_IDENTIFIER: try: self.hum = Humidity(uid, self.ipcon) self.hum.set_humidity_callback_period(1000) self.hum.register_callback(self.hum.CALLBACK_HUMIDITY, self.cb_humidity) except Error as e: self.error_msg.showMessage('Humidity init failed: ' + str(e.description)) self.hum = None elif device_identifier == Barometer.DEVICE_IDENTIFIER: try: self.baro = Barometer(uid, self.ipcon) self.baro.set_air_pressure_callback_period(1000) self.baro.register_callback( self.baro.CALLBACK_AIR_PRESSURE, self.cb_air_pressure) except Error as e: self.error_msg.showMessage('Barometer init failed: ' + str(e.description)) self.baro = None def cb_connected(self, connected_reason): if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT: while True: try: self.ipcon.enumerate() break except Error as e: self.error_msg.showMessage('Enumerate Error: ' + str(e.description)) time.sleep(1)
def __init__(self, *args): PluginBase.__init__(self, BrickStepper, *args) self.setupUi(self) self.stepper = self.device self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.decay_widget.hide() self.setting_sync_rect_checkbox = False self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider, self.deceleration_spin, self.deceleration_changed) self.decay_syncer = SliderSpinSyncer(self.decay_slider, self.decay_spin, self.decay_changed) self.enable_checkbox.toggled.connect(self.enable_toggled) self.forward_button.clicked.connect(self.forward_clicked) self.stop_button.clicked.connect(self.stop_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.backward_button.clicked.connect(self.backward_clicked) self.to_button.clicked.connect(self.to_button_clicked) self.steps_button.clicked.connect(self.steps_button_clicked) self.motor_current_button.clicked.connect( self.motor_current_button_clicked) self.minimum_motor_voltage_button.clicked.connect( self.minimum_motor_voltage_button_clicked) self.sync_rect_checkbox.toggled.connect(self.sync_rect_toggled) self.mode_dropbox.currentIndexChanged.connect(self.mode_changed) self.qtcb_position_reached.connect(self.cb_position_reached) self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0 if self.firmware_version >= (2, 3, 1): self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect( lambda checked: self.stepper.enable_status_led() if checked else self.stepper.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None if self.firmware_version >= (1, 1, 4): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.stepper.reset()) self.set_actions([(0, None, [reset])])
class WeatherStation(QApplication): HOST = "localhost" PORT = 4223 ipcon = None lcd = None al = None hum = None baro = None projects = [] active_project = None error_msg = None def __init__(self, args): super(QApplication, self).__init__(args) self.error_msg = QErrorMessage() self.ipcon = IPConnection() signal.signal(signal.SIGINT, self.exit_demo) signal.signal(signal.SIGTERM, self.exit_demo) timer = QTimer(self) timer.setSingleShot(True) timer.timeout.connect(self.connect) timer.start(1) def exit_demo(self, signl=None, frme=None): try: self.ipcon.disconnect() self.timer.stop() self.tabs.destroy() except: pass sys.exit() def open_gui(self): self.main = MainWindow(self) self.main.setFixedSize(730, 430) self.main.setWindowIcon(QIcon(os.path.join(ProgramPath.program_path(), "demo-icon.png"))) self.tabs = QTabWidget() widget = QWidget() layout = QVBoxLayout() layout.addWidget(self.tabs) widget.setLayout(layout) self.main.setCentralWidget(widget) self.projects.append(ProjectEnvDisplay(self.tabs, self)) self.projects.append(ProjectStatistics(self.tabs, self)) self.projects.append(ProjectXively(self.tabs, self)) self.tabs.addTab(self.projects[0], "Display Environment Measurements") self.tabs.addTab(self.projects[1], "Show Statistics with Button Control") self.tabs.addTab(self.projects[2], "Connect to Xively") self.active_project = self.projects[0] self.tabs.currentChanged.connect(self.tabChangedSlot) self.main.setWindowTitle("Starter Kit: Weather Station Demo " + config.DEMO_VERSION) self.main.show() def connect(self): try: self.ipcon.connect(WeatherStation.HOST, WeatherStation.PORT) except Error as e: self.error_msg.showMessage('Connection Error: ' + str(e.description) + "\nBrickd installed and running?") return except socket.error as e: self.error_msg.showMessage('Socket error: ' + str(e) + "\nBrickd installed and running?") return self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.cb_enumerate) self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.cb_connected) try: self.ipcon.enumerate() except Error as e: self.error_msg.showMessage('Enumerate Error: ' + str(e.description)) return self.open_gui() def tabChangedSlot(self, tabIndex): if self.lcd is not None: self.lcd.clear_display() self.active_project = self.projects[tabIndex] def cb_illuminance(self, illuminance): for p in self.projects: p.update_illuminance(illuminance) def cb_humidity(self, humidity): for p in self.projects: p.update_humidity(humidity) def cb_air_pressure(self, air_pressure): for p in self.projects: p.update_air_pressure(air_pressure) try: temperature = self.baro.get_chip_temperature() except Error as e: print('Could not get temperature: ' + str(e.description)) return for p in self.projects: p.update_temperature(temperature) def configure_custom_chars(self): c = [[0x00 for x in range(8)] for y in range(8)] c[0] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff] c[1] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff] c[2] = [0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff] c[3] = [0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff] c[4] = [0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff] c[5] = [0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] c[6] = [0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] c[7] = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] for i in range(len(c)): self.lcd.set_custom_character(i, c[i]); def cb_button_pressed(self, button): for p in self.projects: p.button_pressed(button) def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \ enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE: if device_identifier == LCD20x4.DEVICE_IDENTIFIER: try: self.lcd = LCD20x4(uid, self.ipcon) self.lcd.clear_display() self.lcd.backlight_on() self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED, self.cb_button_pressed) self.configure_custom_chars() except Error as e: self.error_msg.showMessage('LCD 20x4 init failed: ' + str(e.description)) self.lcd = None elif device_identifier == AmbientLight.DEVICE_IDENTIFIER: try: self.al = AmbientLight(uid, self.ipcon) self.al.set_illuminance_callback_period(1000) self.al.register_callback(self.al.CALLBACK_ILLUMINANCE, self.cb_illuminance) except Error as e: self.error_msg.showMessage('Ambient Light init failed: ' + str(e.description)) self.al = None elif device_identifier == Humidity.DEVICE_IDENTIFIER: try: self.hum = Humidity(uid, self.ipcon) self.hum.set_humidity_callback_period(1000) self.hum.register_callback(self.hum.CALLBACK_HUMIDITY, self.cb_humidity) except Error as e: self.error_msg.showMessage('Humidity init failed: ' + str(e.description)) self.hum = None elif device_identifier == Barometer.DEVICE_IDENTIFIER: try: self.baro = Barometer(uid, self.ipcon) self.baro.set_air_pressure_callback_period(1000) self.baro.register_callback(self.baro.CALLBACK_AIR_PRESSURE, self.cb_air_pressure) except Error as e: self.error_msg.showMessage('Barometer init failed: ' + str(e.description)) self.baro = None def cb_connected(self, connected_reason): if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT: while True: try: self.ipcon.enumerate() break except Error as e: self.error_msg.showMessage('Enumerate Error: ' + str(e.description)) time.sleep(1)
class Editor(editor_base.EditorBase): """Representa el editor de texto que aparece en el panel derecho. El editor soporta autocompletado de código y resaltado de sintáxis. """ # Señal es emitida cuando el Editor ejecuta codigo signal_ejecutando = QtCore.pyqtSignal() def __init__(self, main, interpreterLocals, consola_lanas, ventana_interprete): super(Editor, self).__init__() self.cantidad_ejecuciones = 0 self.consola_lanas = consola_lanas self.ventana_interprete = ventana_interprete self.ruta_del_archivo_actual = None self.interpreterLocals = interpreterLocals self.setLineWrapMode(QTextEdit.NoWrap) self._cambios_sin_guardar = False self.main = main self.nombre_de_archivo_sugerido = "" self.watcher = pilasengine.watcher.Watcher( None, self.cuando_cambia_archivo_de_forma_externa) def crear_archivo_inicial(self): dirpath = tempfile.mkdtemp() archivo_temporal = os.path.join(dirpath, "mi_juego.py") archivo = codecs.open(archivo_temporal, "w", 'utf-8') archivo.write(CODIGO_INICIAL) archivo.close() #print("Creando el archivo " + str(archivo_temporal)) self.abrir_archivo_del_proyecto(archivo_temporal) def es_archivo_iniciar_sin_guardar(self): return self.nombre_de_archivo_sugerido == "" def crear_y_seleccionar_archivo(self, nombre): # Quita la extension si llega a tenerla. nombre = nombre.replace('.py', '') nombre += ".py" nombre_de_archivo = nombre if self.ruta_del_archivo_actual: base_path = os.path.abspath( os.path.dirname(self.ruta_del_archivo_actual)) ruta = os.path.join(base_path, unicode(nombre_de_archivo)) else: ruta = unicode(nombre_de_archivo) if os.path.exists(ruta): self._tmp_dialog = QErrorMessage(self) self._tmp_dialog.showMessage("Ya existe un archivo con ese nombre") else: self._crear_archivo_nuevo_en(ruta) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() def _crear_archivo_nuevo_en(self, ruta): fo = open(ruta, "wb") fo.write("# contenido") fo.close() def obtener_archivos_del_proyecto(self): base_path = os.path.dirname(self.nombre_de_archivo_sugerido) listado = os.listdir(base_path) return [x for x in listado if x.endswith('.py')] def keyPressEvent(self, event): "Atiene el evento de pulsación de tecla." self._cambios_sin_guardar = True # Permite usar tab como seleccionador de la palabra actual # en el popup de autocompletado. if event.key() in [Qt.Key_Tab]: if self.completer and self.completer.popup().isVisible(): event.ignore() nuevo_evento = QKeyEvent(QKeyEvent.KeyPress, Qt.Key_Return, Qt.NoModifier) try: if self.autocomplete(nuevo_evento): return None except UnicodeEncodeError: pass return None if editor_base.EditorBase.keyPressEvent(self, event): return None # Elimina los pares de caracteres especiales si los encuentra if event.key() == Qt.Key_Backspace: self._eliminar_pares_de_caracteres() self._borrar_un_grupo_de_espacios(event) if self.autocomplete(event): return None if event.key() == Qt.Key_Return: cursor = self.textCursor() block = self.document().findBlockByNumber(cursor.blockNumber()) whitespace = re.match(r"(\s*)", unicode(block.text())).group(1) linea_anterior = str(block.text()[:]) cantidad_espacios = linea_anterior.count(' ') / 4 if linea_anterior[-1:] == ':': whitespace = ' ' * (cantidad_espacios + 1) else: whitespace = ' ' * (cantidad_espacios) QTextEdit.keyPressEvent(self, event) return self.insertPlainText(whitespace) return QTextEdit.keyPressEvent(self, event) def _borrar_un_grupo_de_espacios(self, event): cursor = self.textCursor() block = self.document().findBlockByNumber(cursor.blockNumber()) whitespace = re.match(r"(.*)", unicode(block.text())).group(1) if whitespace.endswith(' '): QTextEdit.keyPressEvent(self, event) QTextEdit.keyPressEvent(self, event) QTextEdit.keyPressEvent(self, event) def tiene_cambios_sin_guardar(self): return self._cambios_sin_guardar def _get_current_line(self): "Obtiene la linea en donde se encuentra el cursor." tc = self.textCursor() tc.select(QTextCursor.LineUnderCursor) return tc.selectedText() def _get_position_in_block(self): tc = self.textCursor() position = tc.positionInBlock() - 1 return position def cargar_contenido_desde_archivo(self, ruta): "Carga todo el contenido del archivo indicado por ruta." with codecs.open(unicode(ruta), 'r', 'utf-8') as archivo: contenido = archivo.read() self.setText(contenido) self.nombre_de_archivo_sugerido = ruta self._cambios_sin_guardar = False def abrir_dialogo_cargar_archivo(self): return QFileDialog.getOpenFileName( self, "Abrir Archivo", self.nombre_de_archivo_sugerido, "Archivos python (*.py)", options=QFileDialog.DontUseNativeDialog) def abrir_archivo_del_proyecto(self, nombre_de_archivo): if self.tiene_cambios_sin_guardar(): if self.mensaje_guardar_cambios_abrir(): if not self.guardar_contenido_con_dialogo(): return else: return if self.ruta_del_archivo_actual: base_path = os.path.dirname(self.ruta_del_archivo_actual) ruta = os.path.join(base_path, unicode(nombre_de_archivo)) else: ruta = unicode(nombre_de_archivo) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() def abrir_archivo_con_dialogo(self): if self.tiene_cambios_sin_guardar(): if self.mensaje_guardar_cambios_abrir(): if not self.guardar_contenido_con_dialogo(): return else: return ruta = self.abrir_dialogo_cargar_archivo() if ruta: ruta = unicode(ruta) self.cargar_contenido_desde_archivo(ruta) self.ruta_del_archivo_actual = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() def cuando_cambia_archivo_de_forma_externa(self): self.recargar_archivo_actual() def recargar_archivo_actual(self): if self.ruta_del_archivo_actual: self.cargar_contenido_desde_archivo(self.ruta_del_archivo_actual) self.ejecutar() def mensaje_guardar_cambios_abrir(self): """Realizar una consulta usando un cuadro de dialogo simple se utiliza cuando hay cambios sin guardar y se desea abrir un archivo. Retorna True si el usuario presiona el boton *Guardar*, Retorna False si el usuario presiona *No*.""" titulo = u"¿Deseas guardar el contenido antes de abrir un archivo?" mensaje = u"El contenido se perdera sino los guardas" mensaje = QMessageBox.question(self, titulo, mensaje, "Guardar", "No") return (not mensaje) def mensaje_guardar_cambios_salir(self): """Realizar una consulta usando un cuadro de dialogo simple se utiliza cuando hay cambios sin guardar y se desa salir del Editor. Retorna 0 si el usuario presiona el boton *Salir sin guardar*, Retorna 1 si el usuario presiona *Guardar* Retorna 2 si presiona *Cancelar*.""" titulo = u"¿Deseas guardar el contenido antes de salir?" mensaje = u"El contenido se perdera sino los guardas" return QMessageBox.question(self, titulo, mensaje, "Salir sin guardar", "Guardar", "Cancelar") def marcar_error_en_la_linea(self, numero, descripcion): hi_selection = QTextEdit.ExtraSelection() hi_selection.format.setBackground(QColor(255, 220, 220)) hi_selection.format.setProperty(QTextFormat.FullWidthSelection, QVariant(True)) hi_selection.cursor = self.textCursor() posicion_linea = self.document().findBlockByLineNumber( numero).position() hi_selection.cursor.setPosition(posicion_linea) hi_selection.cursor.clearSelection() self.setExtraSelections([hi_selection]) def guardar_contenido_con_dialogo(self): ruta = self.abrir_dialogo_guardar_archivo() if not ruta: return False ruta = unicode(ruta) if not ruta.endswith('.py'): ruta += '.py' if ruta: self.guardar_contenido_en_el_archivo(ruta) self._cambios_sin_guardar = False self.ruta_del_archivo_actual = ruta self.nombre_de_archivo_sugerido = ruta self.watcher.cambiar_archivo_a_observar(ruta) self.cargar_contenido_desde_archivo(ruta) self.ejecutar() self.main.actualizar_el_listado_de_archivos() self.main.habilitar_boton_nuevo() return True def guardar_contenido_directamente(self): if self.nombre_de_archivo_sugerido: self.guardar_contenido_en_el_archivo( self.nombre_de_archivo_sugerido) self._cambios_sin_guardar = False self.main.actualizar_el_listado_de_archivos() self.prevenir_live_reload() else: self.guardar_contenido_con_dialogo() def prevenir_live_reload(self): self.watcher.prevenir_reinicio() def salir(self): """Retorna True si puede salir y False si no""" if self.tiene_cambios_sin_guardar(): mensaje = self.mensaje_guardar_cambios_salir() if mensaje == 1: self.guardar_contenido_con_dialogo() elif mensaje == 2: return False return True def obtener_contenido(self): return unicode(self.document().toPlainText()) def ejecutar(self): ruta_personalizada = os.path.dirname(self.ruta_del_archivo_actual) #print "ejecutando texto desde widget editor" texto = self.obtener_contenido() #texto = self.editor.obtener_texto_sanitizado(self) # elimina cabecera de encoding. contenido = re.sub('coding\s*:\s*', '', texto) contenido = contenido.replace('import pilasengine', '') contenido = contenido.replace('pilas = pilasengine.iniciar', 'pilas.reiniciar') for x in contenido.split('\n'): if "__file__" in x: contenido = contenido.replace(x, "# livecoding: " + x + "\n") sys.path.append(ruta_personalizada) self.interpreterLocals['sys'] = sys # Muchos códigos personalizados necesitan cargar imágenes o sonidos # desde el directorio que contiene al archivo. Para hacer esto posible, # se llama a la función "pilas.utils.agregar_ruta_personalizada" con el # path al directorio que representa el script. Así la función "obtener_ruta_al_recurso" # puede evaluar al directorio del script en busca de recursos también. if ruta_personalizada: ruta_personalizada = ruta_personalizada.replace('\\', '/') agregar_ruta_personalizada = 'pilas.utils.agregar_ruta_personalizada("%s")' % ( ruta_personalizada) contenido = contenido.replace( 'pilas.reiniciar(', agregar_ruta_personalizada + '\n' + 'pilas.reiniciar(') modulos_a_recargar = [ x for x in self.interpreterLocals.values() if inspect.ismodule(x) and x.__name__ not in ['pilasengine', 'inspect'] and 'pilasengine.' not in x.__name__ ] for m in modulos_a_recargar: reload(m) self.cantidad_ejecuciones += 1 # Limpia la consola a partir de la primer ejecucion luego de iniciar. if self.cantidad_ejecuciones > 1: self.main.limpiar_interprete() try: exec(contenido, self.interpreterLocals) except Exception, e: self.consola_lanas.insertar_error_desde_exception(e) self.ventana_interprete.mostrar_el_interprete() #self.marcar_error_en_la_linea(10, "pepepe") self.signal_ejecutando.emit()
class Stepper(PluginBase, Ui_Stepper): qtcb_position_reached = pyqtSignal(int) qtcb_under_voltage = pyqtSignal(int) def __init__(self, *args): PluginBase.__init__(self, BrickStepper, *args) self.setupUi(self) self.stepper = self.device self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.decay_widget.hide() self.setting_sync_rect_checkbox = False self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider, self.deceleration_spin, self.deceleration_changed) self.decay_syncer = SliderSpinSyncer(self.decay_slider, self.decay_spin, self.decay_changed) self.enable_checkbox.toggled.connect(self.enable_toggled) self.forward_button.clicked.connect(self.forward_clicked) self.stop_button.clicked.connect(self.stop_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.backward_button.clicked.connect(self.backward_clicked) self.to_button.clicked.connect(self.to_button_clicked) self.steps_button.clicked.connect(self.steps_button_clicked) self.motor_current_button.clicked.connect(self.motor_current_button_clicked) self.minimum_motor_voltage_button.clicked.connect(self.minimum_motor_voltage_button_clicked) self.sync_rect_checkbox.toggled.connect(self.sync_rect_toggled) self.mode_dropbox.currentIndexChanged.connect(self.mode_changed) self.qtcb_position_reached.connect(self.cb_position_reached) self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0 if self.firmware_version >= (1, 1, 4): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.stepper.reset()) self.set_actions(reset) def start(self): self.update_timer.start(100) self.update_start() def stop(self): self.update_timer.stop() def destroy(self): pass def get_url_part(self): return 'stepper' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickStepper.DEVICE_IDENTIFIER def cb_position_reached(self, position): self.position_update(position) self.endis_all(True) def disable_list(self, button_list): for button in button_list: button.setEnabled(False) def endis_all(self, value): self.forward_button.setEnabled(value) self.stop_button.setEnabled(value) self.backward_button.setEnabled(value) self.to_button.setEnabled(value) self.steps_button.setEnabled(value) self.full_brake_button.setEnabled(value) def mode_changed(self, index): try: self.stepper.set_step_mode(1 << index) self.mod = 1 << index except ip_connection.Error: return def forward_clicked(self): try: self.stepper.drive_forward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def backward_clicked(self): try: self.stepper.drive_backward() except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button]) def stop_clicked(self): try: self.stepper.stop() except ip_connection.Error: return self.endis_all(True) def full_brake_clicked(self): try: self.stepper.full_brake() except ip_connection.Error: return self.endis_all(True) def to_button_clicked(self): drive_to = self.to_spin.value() try: self.stepper.set_target_position(drive_to) except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button, self.forward_button, self.backward_button]) def steps_button_clicked(self): drive_steps = self.steps_spin.value() try: self.stepper.set_steps(drive_steps) except ip_connection.Error: return self.disable_list([self.to_button, self.steps_button, self.forward_button, self.backward_button]) def motor_current_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(2500) qid.setIntStep(100) async_call(self.stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.motor_current_selected) qid.setLabelText("Choose motor current in mA.") # "<font color=red>Setting this too high can destroy your Motor.</font>") qid.open() def minimum_motor_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(0) qid.setIntMaximum(40000) qid.setIntStep(100) async_call(self.stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_motor_voltage_selected) qid.setLabelText("Choose minimum motor voltage in mV.") qid.open() def motor_current_selected(self, value): try: self.stepper.set_motor_current(value) except ip_connection.Error: return def minimum_motor_voltage_selected(self, value): try: self.stepper.set_minimum_voltage(value) except ip_connection.Error: return def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov/1000.0, 1) if not self.qem.isVisible(): self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "Stepper_UnderVoltage") def enable_toggled(self, checked): try: if checked: if not self.stepper.is_enabled(): self.endis_all(True) self.stepper.enable() else: if self.stepper.is_enabled(): self.endis_all(False) self.stepper.disable() except ip_connection.Error: return def sync_rect_toggled(self, checked): if not self.setting_sync_rect_checkbox and checked: rc = QMessageBox.warning(get_main_window(), 'Synchronous Rectification', 'If you want to use high speeds (> 10000 steps/s) for a large stepper motor with a ' + 'large inductivity we strongly suggest that you do not enable synchronous rectification. ' + 'Otherwise the Brick may not be able to cope with the load and overheat.', QMessageBox.Ok | QMessageBox.Cancel) if rc != QMessageBox.Ok: self.sync_rect_checkbox.setChecked(False) return try: self.stepper.set_sync_rect(checked) except ip_connection.Error: return self.decay_widget.setVisible(checked) def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev/1000.0, 1) self.external_voltage_label.setText(ev_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv/1000.0, 1) self.minimum_voltage_label.setText(mv_str) def maximum_current_update(self, cur): cur_str = "%gA" % round(cur/1000.0, 1) self.maximum_current_label.setText(cur_str) def position_update(self, pos): pos_str = "%d" % pos self.position_label.setText(pos_str) def remaining_steps_update(self, ste): ste_str = "%d" % ste self.remaining_steps_label.setText(ste_str) def current_velocity_update(self, velocity): velocity_str = "%d" % velocity self.current_velocity_label.setText(velocity_str) self.speedometer.set_velocity(velocity) def mode_update(self, mod): if mod == 8: index = 3 elif mod == 4: index = 2 elif mod == 2: index = 1 else: index = 0 self.mode_dropbox.setCurrentIndex(index) def get_max_velocity_async(self, velocity): if not self.velocity_slider.isSliderDown(): if velocity != self.velocity_slider.sliderPosition(): self.velocity_slider.setSliderPosition(velocity) self.velocity_spin.setValue(velocity) def get_speed_ramping_async(self, ramp): acc, dec = ramp if not self.acceleration_slider.isSliderDown() and \ not self.deceleration_slider.isSliderDown(): if acc != self.acceleration_slider.sliderPosition(): self.acceleration_slider.setSliderPosition(acc) self.acceleration_spin.setValue(acc) if dec != self.deceleration_slider.sliderPosition(): self.deceleration_slider.setSliderPosition(dec) self.deceleration_spin.setValue(dec) def get_decay_async(self, decay): if not self.decay_slider.isSliderDown(): if decay != self.decay_slider.sliderPosition(): self.decay_slider.setSliderPosition(decay) self.decay_spin.setValue(decay) def is_enabled_async(self, enabled): if enabled: if not self.enable_checkbox.isChecked(): self.endis_all(True) self.enable_checkbox.setChecked(True) else: if self.enable_checkbox.isChecked(): self.endis_all(False) self.enable_checkbox.setChecked(False) def is_sync_rect_async(self, sync_rect): self.setting_sync_rect_checkbox = True self.sync_rect_checkbox.setChecked(sync_rect) self.setting_sync_rect_checkbox = False def update_start(self): async_call(self.stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count) async_call(self.stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count) async_call(self.stepper.get_decay, None, self.get_decay_async, self.increase_error_count) async_call(self.stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count) async_call(self.stepper.is_sync_rect, None, self.is_sync_rect_async, self.increase_error_count) def update_data(self): async_call(self.stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count) async_call(self.stepper.get_current_position, None, self.position_update, self.increase_error_count) async_call(self.stepper.get_current_velocity, None, self.current_velocity_update, self.increase_error_count) self.update_counter += 1 if self.update_counter % 10 == 0: async_call(self.stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count) async_call(self.stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count) async_call(self.stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count) async_call(self.stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count) async_call(self.stepper.get_step_mode, None, self.mode_update, self.increase_error_count) def velocity_changed(self, value): try: self.stepper.set_max_velocity(value) except ip_connection.Error: return def acceleration_changed(self, value): dec = self.deceleration_spin.value() try: self.stepper.set_speed_ramping(value, dec) except ip_connection.Error: return def deceleration_changed(self, value): acc = self.acceleration_slider.value() try: self.stepper.set_speed_ramping(acc, value) except ip_connection.Error: return def decay_changed(self, value): try: self.stepper.set_decay(value) except ip_connection.Error: return
class Servo(PluginBase, Ui_Servo): qtcb_under_voltage = pyqtSignal(int) def __init__(self, *args): PluginBase.__init__(self, BrickServo, *args) self.setupUi(self) self.servo = self.device self.position_list = [] self.velocity_list = [] self.acceleration_list = [] self.enable_list = [] self.up_cur = 0 self.up_siv = 0 self.up_eiv = 0 self.up_opv = 0 self.up_mv = 0 self.up_ena = [0] * 7 self.up_pos = [0] * 7 self.up_vel = [0] * 7 self.up_acc = [0] * 7 self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_apply) self.update_timer.setInterval(50) self.alive = True for i in range(1, 8): label = QLabel() label.setText('Off') self.enable_list.append(label) self.status_grid.addWidget(label, i, 1) for i in range(1, 8): pk = PositionKnob() self.position_list.append(pk) self.status_grid.addWidget(pk, i, 2) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.velocity_list.append(cb) self.status_grid.addWidget(cb, i, 3) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.acceleration_list.append(cb) self.status_grid.addWidget(cb, i, 4) self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.test_button.clicked.connect(self.test_button_clicked) self.output_voltage_button.clicked.connect( self.output_voltage_button_clicked) self.servo_dropbox.currentIndexChanged.connect( lambda x: self.update_servo_specific()) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.position_syncer = SliderSpinSyncer(self.position_slider, self.position_spin, self.position_changed) self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.period_syncer = SliderSpinSyncer(self.period_slider, self.period_spin, self.period_changed) self.pulse_width_min_spin.editingFinished.connect( self.pulse_width_spin_finished) self.pulse_width_max_spin.editingFinished.connect( self.pulse_width_spin_finished) self.degree_min_spin.editingFinished.connect(self.degree_spin_finished) self.degree_max_spin.editingFinished.connect(self.degree_spin_finished) self.minimum_voltage_button.clicked.connect( self.minimum_voltage_button_clicked) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) class WorkerThread(QThread): def __init__(self, parent=None, func=None): QThread.__init__(self, parent) self.func = func def run(self): self.func() self.test_event = Event() self.test_thread_object = WorkerThread(self, self.test_thread) self.update_event = Event() self.update_thread_object = WorkerThread(self, self.update_thread) self.update_thread_first_time = False self.update_done_event = Event() self.update_done_event.set() if self.firmware_version >= (2, 3, 1): self.status_led_action = QAction('Status LED', self) self.status_led_action.setCheckable(True) self.status_led_action.toggled.connect( lambda checked: self.servo.enable_status_led() if checked else self.servo.disable_status_led()) self.set_configs([(0, None, [self.status_led_action])]) else: self.status_led_action = None if self.firmware_version >= (1, 1, 3): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.servo.reset()) self.set_actions([(0, None, [reset])]) def start(self): if self.firmware_version >= (2, 3, 1): async_call(self.servo.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count) self.alive = True self.test_event.clear() self.update_done_event.set() self.update_event.set() if not self.test_thread_object.isRunning(): self.test_thread_object.start() if not self.update_thread_object.isRunning(): self.update_thread_object.start() self.update_servo_specific() self.update_timer.start() def stop(self): if self.test_button.text() == "Stop Test": self.test_button_clicked() self.update_timer.stop() self.update_event.clear() self.alive = False self.update_done_event.wait() def destroy(self): self.test_event.set() self.update_event.set() @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickServo.DEVICE_IDENTIFIER def get_period_async(self, per): self.period_spin.setValue(per) self.period_slider.setValue(per) def is_enabled_async(self, ena): self.enable_checkbox.setChecked(ena) def get_position_async(self, pos): self.position_spin.setValue(pos) self.position_slider.setValue(pos) def get_velocity_async(self, vel): self.velocity_spin.setValue(vel) self.velocity_slider.setValue(vel) def get_acceleration_async(self, acc): self.acceleration_spin.setValue(acc) self.acceleration_slider.setValue(acc) def get_degree_async(self, deg, i): deg_min, deg_max = deg self.degree_min_spin.setValue(deg_min) self.degree_max_spin.setValue(deg_max) self.position_slider.setMinimum(deg_min) self.position_slider.setMaximum(deg_max) self.position_spin.setMinimum(deg_min) self.position_spin.setMaximum(deg_max) self.position_list[i].set_total_angle((deg_max - deg_min) / 100) self.position_list[i].set_range(deg_min / 100, deg_max / 100) def get_pulse_width_async(self, pulse): pulse_min, pulse_max = pulse self.pulse_width_min_spin.setValue(pulse_min) self.pulse_width_max_spin.setValue(pulse_max) def update_servo_specific(self): i = self.selected_servo() if i == 255: self.enable_checkbox.setChecked(False) return async_call(self.servo.get_position, i, self.get_position_async, self.increase_error_count) async_call(self.servo.get_velocity, i, self.get_velocity_async, self.increase_error_count) async_call(self.servo.get_acceleration, i, self.get_acceleration_async, self.increase_error_count) async_call(self.servo.get_period, i, self.get_period_async, self.increase_error_count) async_call(self.servo.is_enabled, i, self.is_enabled_async, self.increase_error_count) def get_lambda_deg(i): return lambda x: self.get_degree_async(x, i) async_call(self.servo.get_degree, i, get_lambda_deg(i), self.increase_error_count) async_call(self.servo.get_pulse_width, i, self.get_pulse_width_async, self.increase_error_count) def error_handler(self, error): pass def servo_current_update(self, value): self.current_label.setText(str(value) + "mA") def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv / 1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev / 1000.0, 1) self.external_voltage_label.setText(ev_str) def output_voltage_update(self, ov): ov_str = "%gV" % round(ov / 1000.0, 1) self.output_voltage_label.setText(ov_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv / 1000.0, 1) self.minimum_voltage_label.setText(mv_str) def position_update(self, i, pos): self.position_list[i].set_value(pos / 100) def velocity_update(self, i, vel): self.velocity_list[i].set_height(vel * 100 / 0xFFFF) def acceleration_update(self, i, acc): self.acceleration_list[i].set_height(acc * 100 / 0xFFFF) def deactivate_servo(self, i): if self.enable_list[i].text() != 'Off': self.velocity_list[i].grey() self.acceleration_list[i].grey() def activate_servo(self, i): if self.enable_list[i].text() != 'On': self.velocity_list[i].color() self.acceleration_list[i].color() def selected_servo(self): try: return int(self.servo_dropbox.currentText()[-1:]) except: return 255 def enable_state_changed(self, state): s = self.selected_servo() try: if state == Qt.Checked: self.servo.enable(s) elif state == Qt.Unchecked: self.servo.disable(s) except ip_connection.Error: return def update_apply(self): if not self.update_thread_first_time: return self.servo_current_update(self.up_cur) self.stack_input_voltage_update(self.up_siv) self.external_input_voltage_update(self.up_eiv) self.output_voltage_update(self.up_opv) self.minimum_voltage_update(self.up_mv) for i in range(7): if self.up_ena[i]: self.activate_servo(i) self.position_update(i, self.up_pos[i]) self.velocity_update(i, self.up_vel[i]) self.acceleration_update(i, self.up_acc[i]) self.enable_list[i].setText('On') else: self.deactivate_servo(i) self.enable_list[i].setText('Off') def update_thread(self): while self.alive: time.sleep(0.1) try: servo = self.selected_servo() if servo == 255: self.up_cur = self.servo.get_overall_current() else: self.up_cur = self.servo.get_servo_current(servo) self.up_siv = self.servo.get_stack_input_voltage() self.up_eiv = self.servo.get_external_input_voltage() self.up_opv = self.servo.get_output_voltage() self.up_mv = self.servo.get_minimum_voltage() for i in range(7): self.up_ena[i] = self.servo.is_enabled(i) if self.up_ena[i]: self.activate_servo(i) self.up_pos[i] = self.servo.get_current_position(i) self.up_vel[i] = self.servo.get_current_velocity(i) self.up_acc[i] = self.servo.get_acceleration(i) #self.update_apply() self.update_done_event.set() self.update_event.wait() self.update_done_event.clear() except ip_connection.Error: pass self.update_thread_first_time = True self.update_done_event.set() def test_thread(self): def test(num, ena, acc, vel, pos): if not self.alive: return try: if ena: self.servo.enable(num) else: self.servo.disable(num) self.servo.set_acceleration(num, acc) self.servo.set_velocity(num, vel) self.servo.set_position(num, pos) except ip_connection.Error: return def random_test(): for i in range(7): test(i, random.randrange(0, 2), random.randrange(0, 65536), random.randrange(0, 65536), random.randrange(-9000, 9001)) while self.alive: self.test_event.wait() if not self.alive: return # Full Speed left for 2 seconds for i in range(7): test(i, True, 65535, 65535, 9000) time.sleep(2) self.test_event.wait() if not self.alive: return # Full Speed right for 2 seconds for i in range(7): test(i, True, 65535, 65535, -9000) time.sleep(2) self.test_event.wait() if not self.alive: return # Test different speeds for i in range(19): for j in range(7): test(j, True, 65535, 65535 * i / 18, -9000 + i * 1000) time.sleep(0.1) self.test_event.wait() if not self.alive: return time.sleep(1) self.test_event.wait() if not self.alive: return # Test acceleration for i in range(7): test(i, True, 100, 65535, -9000) time.sleep(3) self.test_event.wait() if not self.alive: return # Random for 3 seconds random_test() time.sleep(3) def test_button_clicked(self): if self.test_button.text() == "Start Test": self.test_button.setText("Stop Test") self.test_event.set() else: self.test_button.setText("Start Test") self.test_event.clear() def output_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(2000) qid.setIntMaximum(9000) qid.setIntStep(100) async_call(self.servo.get_output_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.output_voltage_selected) qid.setLabelText("Choose Output Voltage in mV.") # "<font color=red>Setting this too high can destroy your servo.</font>") qid.open() def output_voltage_selected(self, value): try: self.servo.set_output_voltage(value) except ip_connection.Error: return def position_changed(self, value): try: self.servo.set_position(self.selected_servo(), value) except ip_connection.Error: return def velocity_changed(self, value): try: self.servo.set_velocity(self.selected_servo(), value) except ip_connection.Error: return def acceleration_changed(self, value): try: self.servo.set_acceleration(self.selected_servo(), value) except ip_connection.Error: return def period_changed(self, value): try: self.servo.set_period(self.selected_servo(), value) except ip_connection.Error: return def pulse_width_spin_finished(self): try: self.servo.set_pulse_width(self.selected_servo(), self.pulse_width_min_spin.value(), self.pulse_width_max_spin.value()) except ip_connection.Error: return def degree_spin_finished(self): min = self.degree_min_spin.value() max = self.degree_max_spin.value() servo = self.selected_servo() self.position_slider.setMinimum(min) self.position_slider.setMaximum(max) self.position_spin.setMinimum(min) self.position_spin.setMaximum(max) if servo == 255: for i in range(7): self.position_list[i].set_total_angle((max - min) / 100) self.position_list[i].set_range(min / 100, max / 100) else: self.position_list[servo].set_total_angle((max - min) / 100) self.position_list[servo].set_range(min / 100, max / 100) try: self.servo.set_degree(servo, min, max) except ip_connection.Error: return def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov / 1000.0, 1) if not self.qem.isVisible(): self.qem.showMessage( "Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "Servo_UnterVoltage") def minimum_voltage_selected(self, value): try: self.servo.set_minimum_voltage(value) except ip_connection.Error: return def minimum_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(5000) qid.setIntMaximum(0xFFFF) qid.setIntStep(100) async_call(self.servo.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_voltage_selected) qid.setLabelText("Choose minimum servo voltage in mV.") qid.open()
def __init__(self, ipcon, uid): PluginBase.__init__(self, ipcon, uid) self.setupUi(self) self.servo = brick_servo.Servo(self.uid) self.device = self.servo self.ipcon.add_device(self.servo) self.version = '.'.join(map(str, self.servo.get_version()[1])) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_apply) self.update_timer.setInterval(0) self.update_timer.setSingleShot(True) layout = QVBoxLayout(self) layout.addWidget(QLabel('Servo')) self.position_list = [] self.velocity_list = [] self.acceleration_list = [] self.enable_list = [] self.up_ena = [0] * 7 self.up_pos = [0] * 7 self.up_vel = [0] * 7 self.up_acc = [0] * 7 self.alive = True for i in range(1, 8): label = QLabel() label.setText('Off') self.enable_list.append(label) self.status_grid.addWidget(label, i, 1) for i in range(1, 8): pk = PositionKnob() self.position_list.append(pk) self.status_grid.addWidget(pk, i, 2) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.velocity_list.append(cb) self.status_grid.addWidget(cb, i, 3) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.acceleration_list.append(cb) self.status_grid.addWidget(cb, i, 4) self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.test_button.clicked.connect(self.test_button_clicked) self.output_voltage_button.clicked.connect( self.output_voltage_button_clicked) self.servo_dropbox.currentIndexChanged.connect( lambda x: self.update_servo_specific()) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.position_slider.sliderReleased.connect( self.position_slider_released) self.position_slider.valueChanged.connect(self.position_spin.setValue) self.position_spin.editingFinished.connect(self.position_spin_finished) self.velocity_slider.sliderReleased.connect( self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect( self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect( self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect( self.acceleration_spin_finished) self.period_slider.sliderReleased.connect(self.period_slider_released) self.period_slider.valueChanged.connect(self.period_spin.setValue) self.period_spin.editingFinished.connect(self.period_spin_finished) self.pulse_width_min_spin.editingFinished.connect( self.pulse_width_spin_finished) self.pulse_width_max_spin.editingFinished.connect( self.pulse_width_spin_finished) self.degree_min_spin.editingFinished.connect(self.degree_spin_finished) self.degree_max_spin.editingFinished.connect(self.degree_spin_finished) self.minimum_voltage_button.pressed.connect( self.minimum_voltage_button_pressed) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) class WorkerThread(QThread): def __init__(self, parent=None, func=None): QThread.__init__(self, parent) self.func = func def run(self): self.func() self.test_event = Event() self.test_thread_object = WorkerThread(self, self.test_thread) self.update_event = Event() self.update_thread_object = WorkerThread(self, self.update_thread) self.update_done_event = Event() self.update_done_event.set()
except socket.error: # Good si is correct (on UNIX) otherinstance = True else: # On windows only singleinstance can be trusted otherinstance = True if iswindows else False if not otherinstance and not opts.shutdown_running_calibre: return run_gui(opts, args, listener, app, gui_debug=gui_debug) communicate(opts, args) return 0 if __name__ == "__main__": try: sys.exit(main()) except Exception as err: if not iswindows: raise tb = traceback.format_exc() from PyQt4.QtGui import QErrorMessage logfile = os.path.join(os.path.expanduser("~"), "calibre.log") if os.path.exists(logfile): log = open(logfile).read().decode("utf-8", "ignore") d = QErrorMessage() d.showMessage( ("<b>Error:</b>%s<br><b>Traceback:</b><br>" "%s<b>Log:</b><br>%s") % (unicode(err), unicode(tb).replace("\n", "<br>"), log.replace("\n", "<br>")) )
class Servo(PluginBase, Ui_Servo): qtcb_under_voltage = pyqtSignal(int) def __init__ (self, ipcon, uid): PluginBase.__init__(self, ipcon, uid) self.setupUi(self) self.servo = brick_servo.Servo(self.uid) self.device = self.servo self.ipcon.add_device(self.servo) self.version = '.'.join(map(str, self.servo.get_version()[1])) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_apply) self.update_timer.setInterval(0) self.update_timer.setSingleShot(True) layout = QVBoxLayout(self) layout.addWidget(QLabel('Servo')) self.position_list = [] self.velocity_list = [] self.acceleration_list = [] self.enable_list = [] self.up_ena = [0]*7 self.up_pos = [0]*7 self.up_vel = [0]*7 self.up_acc = [0]*7 self.alive = True for i in range(1, 8): label = QLabel() label.setText('Off') self.enable_list.append(label) self.status_grid.addWidget(label, i, 1) for i in range(1, 8): pk = PositionKnob() self.position_list.append(pk) self.status_grid.addWidget(pk, i, 2) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.velocity_list.append(cb) self.status_grid.addWidget(cb, i, 3) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.acceleration_list.append(cb) self.status_grid.addWidget(cb, i, 4) self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.test_button.clicked.connect(self.test_button_clicked) self.output_voltage_button.clicked.connect(self.output_voltage_button_clicked) self.servo_dropbox.currentIndexChanged.connect(lambda x: self.update_servo_specific()) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.position_slider.sliderReleased.connect(self.position_slider_released) self.position_slider.valueChanged.connect(self.position_spin.setValue) self.position_spin.editingFinished.connect(self.position_spin_finished) self.velocity_slider.sliderReleased.connect(self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished) self.period_slider.sliderReleased.connect(self.period_slider_released) self.period_slider.valueChanged.connect(self.period_spin.setValue) self.period_spin.editingFinished.connect(self.period_spin_finished) self.pulse_width_min_spin.editingFinished.connect(self.pulse_width_spin_finished) self.pulse_width_max_spin.editingFinished.connect(self.pulse_width_spin_finished) self.degree_min_spin.editingFinished.connect(self.degree_spin_finished) self.degree_max_spin.editingFinished.connect(self.degree_spin_finished) self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) class WorkerThread(QThread): def __init__(self, parent = None, func = None): QThread.__init__(self, parent) self.func = func def run(self): self.func() self.test_event = Event() self.test_thread_object = WorkerThread(self, self.test_thread) self.update_event = Event() self.update_thread_object = WorkerThread(self, self.update_thread) self.update_done_event = Event() self.update_done_event.set() def stop(self): if self.test_button.text() == "Stop Test": self.test_button_clicked() self.update_event.clear() self.alive = False self.update_done_event.wait() def start(self): self.alive = True self.test_event.clear() self.update_done_event.set() self.update_event.set() if not self.test_thread_object.isRunning(): self.test_thread_object.start() if not self.update_thread_object.isRunning(): self.update_thread_object.start() self.update_servo_specific() def destroy(self): self.test_event.set() self.update_event.set() @staticmethod def has_name(name): return 'Servo Brick' in name def update_servo_specific(self): i = self.selected_servo() if i == 255: self.enable_checkbox.setCheckState(Qt.Unchecked) return try: pos = self.servo.get_position(i); vel = self.servo.get_velocity(i); acc = self.servo.get_acceleration(i); per = self.servo.get_period(i) ena = self.servo.is_enabled(i) deg_min, deg_max = self.servo.get_degree(i) pulse_min, pulse_max = self.servo.get_pulse_width(i) except ip_connection.Error: return self.position_spin.setValue(pos) self.velocity_spin.setValue(vel) self.acceleration_spin.setValue(acc) self.period_spin.setValue(per) self.position_slider.setValue(pos) self.velocity_slider.setValue(vel) self.acceleration_slider.setValue(acc) self.period_slider.setValue(per) if ena: self.enable_checkbox.setCheckState(Qt.Checked) else: self.enable_checkbox.setCheckState(Qt.Unchecked) self.pulse_width_min_spin.setValue(pulse_min) self.pulse_width_max_spin.setValue(pulse_max) self.degree_min_spin.setValue(deg_min) self.degree_max_spin.setValue(deg_max) self.position_slider.setMinimum(deg_min) self.position_slider.setMaximum(deg_max) self.position_spin.setMinimum(deg_min) self.position_spin.setMaximum(deg_max) self.position_list[i].setTotalAngle((deg_max - deg_min)/100) self.position_list[i].setRange(deg_min/100, deg_max/100) def error_handler(self, error): pass def servo_current_update(self, value): self.current_label.setText(str(value) + "mA") def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev/1000.0, 1) self.external_voltage_label.setText(ev_str) def output_voltage_update(self, ov): ov_str = "%gV" % round(ov/1000.0, 1) self.output_voltage_label.setText(ov_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv/1000.0, 1) self.minimum_voltage_label.setText(mv_str) def position_update(self, i, pos): self.position_list[i].setValue(pos/100) def velocity_update(self, i, vel): self.velocity_list[i].set_height(vel*100/0xFFFF) def acceleration_update(self, i, acc): self.acceleration_list[i].set_height(acc*100/0xFFFF) def deactivate_servo(self, i): if self.enable_list[i].text() != 'Off': self.velocity_list[i].grey() self.acceleration_list[i].grey() def activate_servo(self, i): if self.enable_list[i].text() != 'On': self.velocity_list[i].color() self.acceleration_list[i].color() def selected_servo(self): try: return int(self.servo_dropbox.currentText()[-1:]) except: return 255 def enable_state_changed(self, state): s = self.selected_servo() try: if state == Qt.Checked: self.servo.enable(s) elif state == Qt.Unchecked: self.servo.disable(s) except ip_connection.Error: return def update_apply(self): self.servo_current_update(self.up_cur) self.stack_input_voltage_update(self.up_siv) self.external_input_voltage_update(self.up_eiv) self.output_voltage_update(self.up_opv) self.minimum_voltage_update(self.up_mv) for i in range(7): if self.up_ena[i]: self.activate_servo(i) self.position_update(i, self.up_pos[i]) self.velocity_update(i, self.up_vel[i]) self.acceleration_update(i, self.up_acc[i]) self.enable_list[i].setText('On') else: self.deactivate_servo(i) self.enable_list[i].setText('Off') def update_thread(self): while self.alive: time.sleep(0.1) try: servo = self.selected_servo() if servo == 255: self.up_cur = self.servo.get_overall_current() else: self.up_cur = self.servo.get_servo_current(servo) self.up_siv = self.servo.get_stack_input_voltage() self.up_eiv = self.servo.get_external_input_voltage() self.up_opv = self.servo.get_output_voltage() self.up_mv = self.servo.get_minimum_voltage() for i in range(7): self.up_ena[i] = self.servo.is_enabled(i) if self.up_ena[i]: self.activate_servo(i) self.up_pos[i] = self.servo.get_current_position(i) self.up_vel[i] = self.servo.get_current_velocity(i) self.up_acc[i] = self.servo.get_acceleration(i) self.update_timer.start() #self.update_apply() self.update_done_event.set() self.update_event.wait() self.update_done_event.clear() except ip_connection.Error: pass self.update_done_event.set() def test_thread(self): def test(num, ena, acc, vel, pos): if not self.alive: return try: if ena: self.servo.enable(num) else: self.servo.disable(num) self.servo.set_acceleration(num, acc) self.servo.set_velocity(num, vel) self.servo.set_position(num, pos) except ip_connection.Error: return def random_test(): for i in range(7): test(i, random.randrange(0, 2), random.randrange(0, 65536), random.randrange(0, 65536), random.randrange(-9000, 9001)) while self.alive: self.test_event.wait() if not self.alive: return # Full Speed left for 2 seconds for i in range(7): test(i, True, 65535, 65535, 9000) time.sleep(2) self.test_event.wait() if not self.alive: return # Full Speed right for 2 seconds for i in range(7): test(i, True, 65535, 65535, -9000) time.sleep(2) self.test_event.wait() if not self.alive: return # Test different speeds for i in range(19): for j in range(7): test(j, True, 65535, 65535*i/18, -9000+i*1000) time.sleep(0.1) self.test_event.wait() if not self.alive: return time.sleep(1) self.test_event.wait() if not self.alive: return # Test acceleration for i in range(7): test(i, True, 100, 65535, -9000) time.sleep(3) self.test_event.wait() if not self.alive: return # Random for 3 seconds random_test() time.sleep(3) def test_button_clicked(self): if self.test_button.text() == "Start Test": self.test_button.setText("Stop Test") self.test_event.set() else: self.test_button.setText("Start Test") self.test_event.clear() def output_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(5000) qid.setIntMaximum(27000) qid.setIntStep(100) try: qid.setIntValue(self.servo.get_output_voltage()) except ip_connection.Error: return qid.intValueSelected.connect(self.output_voltage_selected) qid.setLabelText("Choose Output Voltage in mV.") # "<font color=red>Setting this too high can destroy your servo.</font>") qid.open() def output_voltage_selected(self, value): try: self.servo.set_output_voltage(value) except ip_connection.Error: return def position_slider_released(self): value = self.position_slider.value() self.position_spin.setValue(value) try: self.servo.set_position(self.selected_servo(), value) except ip_connection.Error: return def position_spin_finished(self): value = self.position_spin.value() self.position_slider.setValue(value) try: self.servo.set_position(self.selected_servo(), value) except ip_connection.Error: return def velocity_slider_released(self): value = self.velocity_slider.value() self.velocity_spin.setValue(value) try: self.servo.set_velocity(self.selected_servo(), value) except ip_connection.Error: return def velocity_spin_finished(self): value = self.velocity_spin.value() self.velocity_slider.setValue(value) try: self.servo.set_velocity(self.selected_servo(), value) except ip_connection.Error: return def acceleration_slider_released(self): value = self.acceleration_slider.value() self.acceleration_spin.setValue(value) try: self.servo.set_acceleration(self.selected_servo(), value) except ip_connection.Error: return def acceleration_spin_finished(self): value = self.acceleration_spin.value() self.acceleration_slider.setValue(value) try: self.servo.set_acceleration(self.selected_servo(), value) except ip_connection.Error: return def period_slider_released(self): value = self.period_slider.value() self.period_spin.setValue(value) try: self.servo.set_period(self.selected_servo(), value) except ip_connection.Error: return def period_spin_finished(self): value = self.period_spin.value() self.period_slider.setValue(value) try: self.servo.set_period(self.selected_servo(), value) except ip_connection.Error: return def pulse_width_spin_finished(self): try: self.servo.set_pulse_width(self.selected_servo(), self.pulse_width_min_spin.value(), self.pulse_width_max_spin.value()) except ip_connection.Error: return def degree_spin_finished(self): min = self.degree_min_spin.value() max = self.degree_max_spin.value() servo = self.selected_servo() self.position_slider.setMinimum(min) self.position_slider.setMaximum(max) self.position_spin.setMinimum(min) self.position_spin.setMaximum(max) self.position_list[servo].setTotalAngle((max - min)/100) self.position_list[servo].setRange(min/100, max/100) try: self.servo.set_degree(servo, min, max) except ip_connection.Error: return def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov/1000.0, 1) if not self.qem.isVisible(): self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str) def minimum_voltage_selected(self, value): try: self.servo.set_minimum_voltage(value) except ip_connection.Error: return def minimum_voltage_button_pressed(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(5000) qid.setIntMaximum(0xFFFF) qid.setIntStep(100) try: qid.setIntValue(self.servo.get_minimum_voltage()) except ip_connection.Error: return qid.intValueSelected.connect(self.minimum_voltage_selected) qid.setLabelText("Choose minimum servo voltage in mV.") qid.open()
otherinstance = True else: # On windows only singleinstance can be trusted otherinstance = True if iswindows else False if not otherinstance and not opts.shutdown_running_calibre: return run_gui(opts, args, actions, listener, app, gui_debug=gui_debug) communicate(opts, args) return 0 if __name__ == '__main__': try: sys.exit(main()) except Exception as err: if not iswindows: raise tb = traceback.format_exc() from PyQt4.QtGui import QErrorMessage logfile = os.path.join(os.path.expanduser('~'), 'calibre.log') if os.path.exists(logfile): log = open(logfile).read().decode('utf-8', 'ignore') d = QErrorMessage() d.showMessage(('<b>Error:</b>%s<br><b>Traceback:</b><br>' '%s<b>Log:</b><br>%s')%(unicode(err), unicode(tb).replace('\n', '<br>'), log.replace('\n', '<br>')))
def __init__ (self, ipcon, uid): PluginBase.__init__(self, ipcon, uid) self.setupUi(self) self.servo = brick_servo.Servo(self.uid) self.device = self.servo self.ipcon.add_device(self.servo) self.version = '.'.join(map(str, self.servo.get_version()[1])) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_apply) self.update_timer.setInterval(0) self.update_timer.setSingleShot(True) layout = QVBoxLayout(self) layout.addWidget(QLabel('Servo')) self.position_list = [] self.velocity_list = [] self.acceleration_list = [] self.enable_list = [] self.up_ena = [0]*7 self.up_pos = [0]*7 self.up_vel = [0]*7 self.up_acc = [0]*7 self.alive = True for i in range(1, 8): label = QLabel() label.setText('Off') self.enable_list.append(label) self.status_grid.addWidget(label, i, 1) for i in range(1, 8): pk = PositionKnob() self.position_list.append(pk) self.status_grid.addWidget(pk, i, 2) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.velocity_list.append(cb) self.status_grid.addWidget(cb, i, 3) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.acceleration_list.append(cb) self.status_grid.addWidget(cb, i, 4) self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.test_button.clicked.connect(self.test_button_clicked) self.output_voltage_button.clicked.connect(self.output_voltage_button_clicked) self.servo_dropbox.currentIndexChanged.connect(lambda x: self.update_servo_specific()) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.position_slider.sliderReleased.connect(self.position_slider_released) self.position_slider.valueChanged.connect(self.position_spin.setValue) self.position_spin.editingFinished.connect(self.position_spin_finished) self.velocity_slider.sliderReleased.connect(self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished) self.period_slider.sliderReleased.connect(self.period_slider_released) self.period_slider.valueChanged.connect(self.period_spin.setValue) self.period_spin.editingFinished.connect(self.period_spin_finished) self.pulse_width_min_spin.editingFinished.connect(self.pulse_width_spin_finished) self.pulse_width_max_spin.editingFinished.connect(self.pulse_width_spin_finished) self.degree_min_spin.editingFinished.connect(self.degree_spin_finished) self.degree_max_spin.editingFinished.connect(self.degree_spin_finished) self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) class WorkerThread(QThread): def __init__(self, parent = None, func = None): QThread.__init__(self, parent) self.func = func def run(self): self.func() self.test_event = Event() self.test_thread_object = WorkerThread(self, self.test_thread) self.update_event = Event() self.update_thread_object = WorkerThread(self, self.update_thread) self.update_done_event = Event() self.update_done_event.set()
def __init__(self, *args): PluginBase.__init__(self, BrickStepper, *args) self.setupUi(self) self.stepper = self.device self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(5, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider, self.deceleration_spin, self.deceleration_changed) # self.decay_syncer = SliderSpinSyncer(self.decay_slider, # self.decay_spin, # self.decay_changed) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.forward_button.clicked.connect(self.forward_clicked) self.stop_button.clicked.connect(self.stop_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.backward_button.clicked.connect(self.backward_clicked) self.to_button.clicked.connect(self.to_button_clicked) self.steps_button.clicked.connect(self.steps_button_clicked) self.motor_current_button.clicked.connect(self.motor_current_button_clicked) self.minimum_motor_voltage_button.clicked.connect(self.minimum_motor_voltage_button_clicked) self.mode_dropbox.currentIndexChanged.connect(self.mode_changed) self.qtcb_position_reached.connect(self.cb_position_reached) self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0 if self.firmware_version >= (1, 1, 4): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.stepper.reset()) self.set_actions(reset)
class DC(PluginBase, Ui_DC): qtcb_velocity_reached = pyqtSignal(int) qtcb_under_voltage = pyqtSignal(int) qtcb_emergency_shutdown = pyqtSignal() def __init__(self, *args): PluginBase.__init__(self, BrickDC, *args) self.setupUi(self) self.dc = self.device self.encoder_hide_all() self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(4, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.frequency_syncer = SliderSpinSyncer(self.frequency_slider, self.frequency_spin, self.frequency_changed) self.radio_mode_brake.toggled.connect(self.brake_value_changed) self.radio_mode_coast.toggled.connect(self.coast_value_changed) self.minimum_voltage_button.clicked.connect( self.minimum_voltage_button_clicked) self.full_brake_button.clicked.connect(self.full_brake_clicked) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.emergency_signal = None self.under_signal = None self.current_velocity_signal = None self.velocity_reached_signal = None self.qem = QErrorMessage(self) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown) self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN, self.qtcb_emergency_shutdown.emit) self.qtcb_velocity_reached.connect(self.update_velocity) self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED, self.qtcb_velocity_reached.emit) self.cbe_current_velocity = CallbackEmulator( self.dc.get_current_velocity, self.update_velocity, self.increase_error_count) if self.firmware_version >= (1, 1, 3): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.dc.reset()) self.set_actions(reset) # if self.firmware_version >= (2, 0, 1): # self.enable_encoder_checkbox.stateChanged.connect(self.enable_encoder_state_changed) # self.encoder_show() # else: # self.enable_encoder_checkbox.setText('Enable Encoder (FW Version >= 2.0.1 required)') # self.enable_encoder_checkbox.setEnabled(False) def start(self): self.update_timer.start(1000) self.cbe_current_velocity.set_period(100) self.update_start() self.update_data() def stop(self): self.update_timer.stop() self.cbe_current_velocity.set_period(0) def destroy(self): pass def get_url_part(self): return 'dc' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickDC.DEVICE_IDENTIFIER def cb_emergency_shutdown(self): if not self.qem.isVisible(): self.qem.setWindowTitle("Emergency Shutdown") self.qem.showMessage( "Emergency Shutdown: Short-Circuit or Over-Temperature") def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov / 1000.0, 1) if not self.qem.isVisible(): self.qem.setWindowTitle("Under Voltage") self.qem.showMessage( "Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "DC_UnderVoltage") def encoder_hide_all(self): self.enable_encoder_checkbox.hide() self.encoder_hide() def encoder_hide(self): self.p_label.hide() self.p_spinbox.hide() self.i_label.hide() self.i_spinbox.hide() self.d_label.hide() self.d_spinbox.hide() self.st_label.hide() self.st_spinbox.hide() self.cpr_label.hide() self.cpr_spinbox.hide() self.encoder_spacer.hide() def encoder_show(self): self.p_label.show() self.p_spinbox.show() self.i_label.show() self.i_spinbox.show() self.d_label.show() self.d_spinbox.show() self.st_label.show() self.st_spinbox.show() self.cpr_label.show() self.cpr_spinbox.show() self.encoder_spacer.show() def enable_encoder_state_changed(self, state): try: if state == Qt.Checked: self.dc.enable_encoder() self.update_encoder() elif state == Qt.Unchecked: self.dc.disable_encoder() except ip_connection.Error: return def enable_state_changed(self, state): try: if state == Qt.Checked: self.dc.enable() elif state == Qt.Unchecked: self.dc.disable() except ip_connection.Error: return def brake_value_changed(self, checked): if checked: try: self.dc.set_drive_mode(0) except ip_connection.Error: return def coast_value_changed(self, checked): if checked: try: self.dc.set_drive_mode(1) except ip_connection.Error: return def full_brake_clicked(self): try: self.dc.full_brake() except ip_connection.Error: return def minimum_voltage_selected(self, value): try: self.dc.set_minimum_voltage(value) except ip_connection.Error: return def minimum_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(5000) qid.setIntMaximum(0xFFFF) qid.setIntStep(100) async_call(self.dc.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_voltage_selected) qid.setLabelText("Choose minimum motor voltage in mV.") qid.open() def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv / 1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev / 1000.0, 1) self.external_voltage_label.setText(ev_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv / 1000.0, 1) self.minimum_voltage_label.setText(mv_str) def drive_mode_update(self, dm): if dm == 0: self.radio_mode_brake.setChecked(True) self.radio_mode_coast.setChecked(False) else: self.radio_mode_brake.setChecked(False) self.radio_mode_coast.setChecked(True) def current_consumption_update(self, cc): if cc >= 1000: cc_str = "%gA" % round(cc / 1000.0, 1) else: cc_str = "%gmA" % cc self.current_label.setText(cc_str) def update_velocity(self, value): self.speedometer.set_velocity(value) def get_velocity_async(self, velocity): if not self.velocity_slider.isSliderDown(): if velocity != self.velocity_slider.sliderPosition(): self.velocity_slider.setSliderPosition(velocity) self.velocity_spin.setValue(velocity) self.speedometer.set_velocity(velocity) def get_acceleration_async(self, acceleration): if not self.acceleration_slider.isSliderDown(): if acceleration != self.acceleration_slider.sliderPosition(): self.acceleration_slider.setSliderPosition(acceleration) self.acceleration_spin.setValue(acceleration) def get_pwm_frequency_async(self, frequency): if not self.frequency_slider.isSliderDown(): if frequency != self.frequency_slider.sliderPosition(): self.frequency_slider.setSliderPosition(frequency) self.frequency_spin.setValue(frequency) def is_enabled_async(self, enabled): self.enable_checkbox.setChecked(enabled) def is_encoder_enabled_async(self, enabled): self.enable_encoder_checkbox.setChecked(enabled) def get_encoder_config_async(self, cpr): self.cpr_spinbox.setValue(cpr) def get_encoder_pid_config_async(self, pid_config): self.p_spinbox.setValue(pid_config.p) self.i_spinbox.setValue(pid_config.i) self.d_spinbox.setValue(pid_config.d) self.st_spinbox.setValue(pid_config.sample_time) def update_encoder(self): async_call(self.dc.get_encoder_config, None, self.get_encoder_config_async, self.increase_error_count) async_call(self.dc.get_encoder_pid_config, None, self.get_encoder_pid_config_async, self.increase_error_count) async_call(self.dc.is_encoder_enabled, None, self.is_encoder_enabled_async, self.increase_error_count) def update_start(self): async_call(self.dc.get_drive_mode, None, self.drive_mode_update, self.increase_error_count) async_call(self.dc.get_velocity, None, self.get_velocity_async, self.increase_error_count) async_call(self.dc.get_acceleration, None, self.get_acceleration_async, self.increase_error_count) async_call(self.dc.get_pwm_frequency, None, self.get_pwm_frequency_async, self.increase_error_count) async_call(self.dc.is_enabled, None, self.is_enabled_async, self.increase_error_count) # if self.firmware_version >= (2, 0, 1): # self.update_encoder() def update_data(self): async_call(self.dc.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count) async_call(self.dc.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count) async_call(self.dc.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count) async_call(self.dc.get_current_consumption, None, self.current_consumption_update, self.increase_error_count) def acceleration_changed(self, value): try: self.dc.set_acceleration(value) except ip_connection.Error: return def velocity_changed(self, value): try: self.dc.set_velocity(value) except ip_connection.Error: return def frequency_changed(self, value): try: self.dc.set_pwm_frequency(value) except ip_connection.Error: return
class ProjectXively(QWidget): qtcb_update_illuminance = pyqtSignal(float) qtcb_update_air_pressure = pyqtSignal(float) qtcb_update_temperature = pyqtSignal(float) qtcb_update_humidity = pyqtSignal(float) qtcb_button_pressed = pyqtSignal(int) lcdwidget = None xively_host = "api.xively.com" xively_agent = "Tinkerforge Starter Kit Weather Station Demo" xively_channel = "Enter Feed ID here" xively_api_key = "Enter API Key here" xively_items = {} xively_headers = None xively_params = "" xively_update_rate = 5 # in minutes text_agent = None text_channel = None text_api_key = None number_update_rate = None save_button = None xively_timer = None error_message = None label_upload_active = None last_upload = None def __init__(self, parent, app): super(QWidget, self).__init__() self.lcdwidget = LCDWidget(self, app) self.lcdwidget.hide() self.text_agent = QLineEdit(self) self.text_agent.setText(self.xively_agent) self.text_channel = QLineEdit(self) self.text_channel.setText(self.xively_channel) self.text_api_key = QLineEdit(self) self.text_api_key.setText(self.xively_api_key) self.number_update_rate = QSpinBox(self) self.number_update_rate.setRange(1, 1440) self.number_update_rate.setSuffix(' min') self.number_update_rate.setValue(self.xively_update_rate) layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout1.addStretch() layout1.addLayout(layout2) layout1.addStretch() layout2.addSpacerItem(QSpacerItem(LCDWidget.FIXED_WIDGTH, 0)) label = QLabel(self) label.setText( "Project: <b>Connect to Xively</b>. This project uploads the measured values to Xively. Please find documentation how to configure it and program sources in Python <a href=\"http://www.tinkerforge.com/en/doc/Kits/WeatherStation/WeatherStation.html#connect-to-xively\">here</a>.<br>" ) label.setTextFormat(Qt.RichText) label.setTextInteractionFlags(Qt.TextBrowserInteraction) label.setOpenExternalLinks(True) label.setWordWrap(True) label.setAlignment(Qt.AlignJustify) layout2.addSpacing(10) layout2.addWidget(label) layout2.addSpacing(10) layout3a = QHBoxLayout() label = QLabel("Agent Description:") label.setMinimumWidth(150) layout3a.addWidget(label) layout3a.addWidget(self.text_agent, 1) layout2.addLayout(layout3a) layout2.addSpacing(10) layout3b = QHBoxLayout() label = QLabel("Feed:") label.setMinimumWidth(150) layout3b.addWidget(label) layout3b.addWidget(self.text_channel, 1) layout2.addLayout(layout3b) layout2.addSpacing(10) layout3c = QHBoxLayout() label = QLabel("API Key:") label.setMinimumWidth(150) layout3c.addWidget(label) layout3c.addWidget(self.text_api_key, 1) layout2.addLayout(layout3c) layout2.addSpacing(10) layout3d = QHBoxLayout() label = QLabel("Update Rate:") label.setMinimumWidth(150) layout3d.addWidget(label) layout3d.addWidget(self.number_update_rate, 1) layout2.addLayout(layout3d) layout2.addSpacing(10) self.label_upload_active = QLabel("Not Active", self) self.label_upload_active.setMinimumWidth(150) font = QFont() font.setPixelSize(20) self.label_upload_active.setFont(font) self.set_active_label(False) self.save_button = QPushButton("Save/Activate") layout4 = QHBoxLayout() layout4.addWidget(self.label_upload_active) layout4.addWidget(self.save_button, 1) layout2.addLayout(layout4) layout2.addStretch() self.setLayout(layout1) self.qtcb_update_illuminance.connect(self.update_illuminance_data_slot) self.qtcb_update_air_pressure.connect( self.update_air_pressure_data_slot) self.qtcb_update_temperature.connect(self.update_temperature_data_slot) self.qtcb_update_humidity.connect(self.update_humidity_data_slot) self.qtcb_button_pressed.connect(self.button_pressed_slot) self.save_button.clicked.connect(self.save_configuration) self.lcdwidget.clear(self) self.error_message = QErrorMessage(self) def set_active_label(self, value): palette = self.label_upload_active.palette() if value: palette.setColor(self.foregroundRole(), Qt.darkGreen) self.label_upload_active.setText("Active") else: palette.setColor(self.foregroundRole(), Qt.red) self.label_upload_active.setText("Not Active") self.label_upload_active.setPalette(palette) def save_configuration(self): try: self.xively_agent = str(self.text_agent.text()).decode('ascii') self.xively_channel = str(self.text_channel.text()).decode('ascii') self.xively_api_key = str(self.text_api_key.text()).decode('ascii') except: self.error_message.showMessage( 'Agent, Feed and API Key can only contain ASCII characters') return self.xively_update_rate = self.number_update_rate.value() self.xively_headers = { "Content-Type": "application/x-www-form-urlencoded", "X-ApiKey": self.xively_api_key, "User-Agent": self.xively_agent, } self.xively_params = "/v2/feeds/" + self.xively_channel if self.xively_timer is None: self.xively_timer = QTimer(self) self.xively_timer.timeout.connect(self.update_xively) self.xively_timer.start(self.xively_update_rate * 60 * 1000) self.set_active_label(True) self.update_xively() def write_lcd(self): if self.last_upload == None: tmp = "Last: Never" else: tmp = "Last: " + self.last_upload self.lcdwidget.write_line(0, 0, "Xively Upload", self) self.lcdwidget.write_line(2, 0, tmp, self) def update_xively(self): if len(self.xively_items) == 0: return stream_items = [] for identifier, value in self.xively_items.items(): stream_items.append({ 'id': identifier, 'current_value': value[0], 'min_value': value[1], 'max_value': value[2] }) data = {'version': '1.0.0', 'datastreams': stream_items} self.xively_items = {} body = json.dumps(data) try: http = httplib.HTTPSConnection(self.xively_host) http.request('PUT', self.xively_params, body, self.xively_headers) response = http.getresponse() http.close() if response.status != 200: self.error_message.showMessage( 'Could not upload to xively -> Response:' + str(response.status) + ': ' + response.reason + '. Check your configuration.') self.xively_timer.stop() self.xively_timer = None self.set_active_label(False) return except Exception as e: self.error_message.showMessage('HTTP error: ' + str(e)) self.xively_timer.stop() self.xively_timer = None self.set_active_label(False) return # set upload time if upload was a success self.last_upload = time.strftime("%H:%M:%S") def put(self, identifier, value): self.write_lcd() try: _, min_value, max_value = self.xively_items[identifier] if value < min_value: min_value = value if value > max_value: max_value = value self.xively_items[identifier] = (value, min_value, max_value) except: self.xively_items[identifier] = (value, value, value) def update_illuminance_data_slot(self, illuminance): self.put('AmbientLight', illuminance) def update_illuminance(self, illuminance): self.qtcb_update_illuminance.emit(illuminance) def update_humidity_data_slot(self, humidity): self.put('Humidity', humidity) def update_humidity(self, humidity): self.qtcb_update_humidity.emit(humidity) def update_air_pressure_data_slot(self, air_pressure): self.put('AirPressure', air_pressure) def update_air_pressure(self, air_pressure): self.qtcb_update_air_pressure.emit(air_pressure) def update_temperature_data_slot(self, temperature): self.put('Temperature', temperature) def update_temperature(self, temperature): self.qtcb_update_temperature.emit(temperature) def button_pressed_slot(self, button): pass def button_pressed(self, button): self.qtcb_button_pressed.emit(button)
def __init__(self, parent, app): super(QWidget, self).__init__() self.lcdwidget = LCDWidget(self, app) self.lcdwidget.hide() self.text_agent = QLineEdit(self) self.text_agent.setText(self.xively_agent) self.text_channel = QLineEdit(self) self.text_channel.setText(self.xively_channel) self.text_api_key = QLineEdit(self) self.text_api_key.setText(self.xively_api_key) self.number_update_rate = QSpinBox(self) self.number_update_rate.setRange(1, 1440) self.number_update_rate.setSuffix(' min') self.number_update_rate.setValue(self.xively_update_rate) layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout1.addStretch() layout1.addLayout(layout2) layout1.addStretch() layout2.addSpacerItem(QSpacerItem(LCDWidget.FIXED_WIDGTH, 0)) label = QLabel(self) label.setText("Project: <b>Connect to Xively</b>. This project uploads the measured values to Xively. Please find documentation how to configure it and program sources in Python <a href=\"http://www.tinkerforge.com/en/doc/Kits/WeatherStation/WeatherStation.html#connect-to-xively\">here</a>.<br>") label.setTextFormat(Qt.RichText) label.setTextInteractionFlags(Qt.TextBrowserInteraction) label.setOpenExternalLinks(True) label.setWordWrap(True) label.setAlignment(Qt.AlignJustify) layout2.addSpacing(10) layout2.addWidget(label) layout2.addSpacing(10) layout3a = QHBoxLayout() label = QLabel("Agent Description:") label.setMinimumWidth(150) layout3a.addWidget(label) layout3a.addWidget(self.text_agent, 1) layout2.addLayout(layout3a) layout2.addSpacing(10) layout3b = QHBoxLayout() label = QLabel("Feed:") label.setMinimumWidth(150) layout3b.addWidget(label) layout3b.addWidget(self.text_channel, 1) layout2.addLayout(layout3b) layout2.addSpacing(10) layout3c = QHBoxLayout() label = QLabel("API Key:") label.setMinimumWidth(150) layout3c.addWidget(label) layout3c.addWidget(self.text_api_key, 1) layout2.addLayout(layout3c) layout2.addSpacing(10) layout3d = QHBoxLayout() label = QLabel("Update Rate:") label.setMinimumWidth(150) layout3d.addWidget(label) layout3d.addWidget(self.number_update_rate, 1) layout2.addLayout(layout3d) layout2.addSpacing(10) self.label_upload_active = QLabel("Not Active", self) self.label_upload_active.setMinimumWidth(150) font = QFont() font.setPixelSize(20) self.label_upload_active.setFont(font) self.set_active_label(False) self.save_button = QPushButton("Save/Activate") layout4 = QHBoxLayout() layout4.addWidget(self.label_upload_active) layout4.addWidget(self.save_button, 1) layout2.addLayout(layout4) layout2.addStretch() self.setLayout(layout1) self.qtcb_update_illuminance.connect(self.update_illuminance_data_slot) self.qtcb_update_air_pressure.connect(self.update_air_pressure_data_slot) self.qtcb_update_temperature.connect(self.update_temperature_data_slot) self.qtcb_update_humidity.connect(self.update_humidity_data_slot) self.qtcb_button_pressed.connect(self.button_pressed_slot) self.save_button.clicked.connect(self.save_configuration) self.lcdwidget.clear(self) self.error_message = QErrorMessage(self)
def __init__(self, ipcon, uid, version): PluginBase.__init__(self, ipcon, uid, 'Stepper Brick', version) self.setupUi(self) self.stepper = BrickStepper(uid, ipcon) self.device = self.stepper self.endis_all(False) self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(5, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.velocity_slider.sliderReleased.connect(self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished) self.deceleration_slider.sliderReleased.connect(self.deceleration_slider_released) self.deceleration_slider.valueChanged.connect(self.deceleration_spin.setValue) self.deceleration_spin.editingFinished.connect(self.deceleration_spin_finished) # self.decay_slider.sliderReleased.connect(self.decay_slider_released) # self.decay_slider.valueChanged.connect(self.decay_spin.setValue) # self.decay_spin.editingFinished.connect(self.decay_spin_finished) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.forward_button.pressed.connect(self.forward_pressed) self.stop_button.pressed.connect(self.stop_pressed) self.full_brake_button.pressed.connect(self.full_brake_pressed) self.backward_button.pressed.connect(self.backward_pressed) self.to_button.pressed.connect(self.to_button_pressed) self.steps_button.pressed.connect(self.steps_button_pressed) self.motor_current_button.pressed.connect(self.motor_current_button_pressed) self.minimum_motor_voltage_button.pressed.connect(self.minimum_motor_voltage_button_pressed) self.mode_dropbox.currentIndexChanged.connect(self.mode_changed) self.qtcb_position_reached.connect(self.cb_position_reached) self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, self.qtcb_position_reached.emit) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.update_data_async_thread = None self.ste = 0 self.pos = 0 self.current_velocity = 0 self.cur = 0 self.sv = 0 self.ev = 0 self.mv = 0 self.mod = 0
def __init__(self, parent, app): super(QWidget, self).__init__() self.lcdwidget = LCDWidget(self, app) self.lcdwidget.hide() self.text_agent = QLineEdit(self) self.text_agent.setText(self.xively_agent) self.text_channel = QLineEdit(self) self.text_channel.setText(self.xively_channel) self.text_api_key = QLineEdit(self) self.text_api_key.setText(self.xively_api_key) self.number_update_rate = QSpinBox(self) self.number_update_rate.setRange(1, 1440) self.number_update_rate.setSuffix(' min') self.number_update_rate.setValue(self.xively_update_rate) layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout1.addStretch() layout1.addLayout(layout2) layout1.addStretch() layout2.addSpacerItem(QSpacerItem(LCDWidget.FIXED_WIDGTH, 0)) label = QLabel(self) label.setText( "Project: <b>Connect to Xively</b>. This project uploads the measured values to Xively. Please find documentation how to configure it and program sources in Python <a href=\"http://www.tinkerforge.com/en/doc/Kits/WeatherStation/WeatherStation.html#connect-to-xively\">here</a>.<br>" ) label.setTextFormat(Qt.RichText) label.setTextInteractionFlags(Qt.TextBrowserInteraction) label.setOpenExternalLinks(True) label.setWordWrap(True) label.setAlignment(Qt.AlignJustify) layout2.addSpacing(10) layout2.addWidget(label) layout2.addSpacing(10) layout3a = QHBoxLayout() label = QLabel("Agent Description:") label.setMinimumWidth(150) layout3a.addWidget(label) layout3a.addWidget(self.text_agent, 1) layout2.addLayout(layout3a) layout2.addSpacing(10) layout3b = QHBoxLayout() label = QLabel("Feed:") label.setMinimumWidth(150) layout3b.addWidget(label) layout3b.addWidget(self.text_channel, 1) layout2.addLayout(layout3b) layout2.addSpacing(10) layout3c = QHBoxLayout() label = QLabel("API Key:") label.setMinimumWidth(150) layout3c.addWidget(label) layout3c.addWidget(self.text_api_key, 1) layout2.addLayout(layout3c) layout2.addSpacing(10) layout3d = QHBoxLayout() label = QLabel("Update Rate:") label.setMinimumWidth(150) layout3d.addWidget(label) layout3d.addWidget(self.number_update_rate, 1) layout2.addLayout(layout3d) layout2.addSpacing(10) self.label_upload_active = QLabel("Not Active", self) self.label_upload_active.setMinimumWidth(150) font = QFont() font.setPixelSize(20) self.label_upload_active.setFont(font) self.set_active_label(False) self.save_button = QPushButton("Save/Activate") layout4 = QHBoxLayout() layout4.addWidget(self.label_upload_active) layout4.addWidget(self.save_button, 1) layout2.addLayout(layout4) layout2.addStretch() self.setLayout(layout1) self.qtcb_update_illuminance.connect(self.update_illuminance_data_slot) self.qtcb_update_air_pressure.connect( self.update_air_pressure_data_slot) self.qtcb_update_temperature.connect(self.update_temperature_data_slot) self.qtcb_update_humidity.connect(self.update_humidity_data_slot) self.qtcb_button_pressed.connect(self.button_pressed_slot) self.save_button.clicked.connect(self.save_configuration) self.lcdwidget.clear(self) self.error_message = QErrorMessage(self)
class DC(PluginBase, Ui_DC): qtcb_position_reached = pyqtSignal(int) qtcb_under_voltage = pyqtSignal(int) qtcb_emergency_shutdown = pyqtSignal() def __init__(self, ipcon, uid, version): PluginBase.__init__(self, ipcon, uid, 'DC Brick', version) self.setupUi(self) self.encoder_hide_all() self.dc = BrickDC(uid, ipcon) self.device = self.dc self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_data) self.speedometer = SpeedoMeter() self.vertical_layout_right.insertWidget(4, self.speedometer) self.new_value = 0 self.update_counter = 0 self.full_brake_time = 0 self.velocity_slider.sliderReleased.connect(self.velocity_slider_released) self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue) self.velocity_spin.editingFinished.connect(self.velocity_spin_finished) self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released) self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue) self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished) self.frequency_slider.sliderReleased.connect(self.frequency_slider_released) self.frequency_slider.valueChanged.connect(self.frequency_spin.setValue) self.frequency_spin.editingFinished.connect(self.frequency_spin_finished) self.radio_mode_brake.toggled.connect(self.brake_value_changed) self.radio_mode_coast.toggled.connect(self.coast_value_changed) self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed) self.full_brake_button.pressed.connect(self.full_brake_pressed) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.emergency_signal = None self.under_signal = None self.current_velocity_signal = None self.velocity_reached_signal = None self.qem = QErrorMessage(self) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown) self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN, self.qtcb_emergency_shutdown.emit) self.qtcb_position_reached.connect(self.update_velocity) self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED, self.qtcb_position_reached.emit) self.dc.register_callback(self.dc.CALLBACK_CURRENT_VELOCITY, self.qtcb_position_reached.emit) # if self.version >= (2, 0, 1): # self.enable_encoder_checkbox.stateChanged.connect(self.enable_encoder_state_changed) # self.encoder_show() # else: # self.enable_encoder_checkbox.setText('Enable Encoder (Firmware >= 2.01 required)') # self.enable_encoder_checkbox.setEnabled(False) def start(self): self.update_timer.start(1000) async_call(self.dc.set_current_velocity_period, 100, None, self.increase_error_count) self.update_start() self.update_data() def stop(self): self.update_timer.stop() async_call(self.dc.set_current_velocity_period, 0, None, self.increase_error_count) def has_reset_device(self): return self.version >= (1, 1, 3) def reset_device(self): if self.has_reset_device(): self.dc.reset() def is_brick(self): return True def get_url_part(self): return 'dc' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickDC.DEVICE_IDENTIFIER def cb_emergency_shutdown(self): if not self.qem.isVisible(): self.qem.setWindowTitle("Emergency Shutdown") self.qem.showMessage("Emergency Shutdown: Short-Circuit or Over-Temperature") def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov/1000.0, 1) if not self.qem.isVisible(): self.qem.setWindowTitle("Under Voltage") self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "DC_UnderVoltage") def encoder_hide_all(self): self.enable_encoder_checkbox.hide() self.encoder_hide() def encoder_hide(self): self.p_label.hide() self.p_spinbox.hide() self.i_label.hide() self.i_spinbox.hide() self.d_label.hide() self.d_spinbox.hide() self.st_label.hide() self.st_spinbox.hide() self.cpr_label.hide() self.cpr_spinbox.hide() self.encoder_spacer.hide() def encoder_show(self): self.p_label.show() self.p_spinbox.show() self.i_label.show() self.i_spinbox.show() self.d_label.show() self.d_spinbox.show() self.st_label.show() self.st_spinbox.show() self.cpr_label.show() self.cpr_spinbox.show() self.encoder_spacer.show() def enable_encoder_state_changed(self, state): try: if state == Qt.Checked: self.dc.enable_encoder() self.update_encoder() elif state == Qt.Unchecked: self.dc.disable_encoder() except ip_connection.Error: return def enable_state_changed(self, state): try: if state == Qt.Checked: self.dc.enable() elif state == Qt.Unchecked: self.dc.disable() except ip_connection.Error: return def brake_value_changed(self, checked): if checked: try: self.dc.set_drive_mode(0) except ip_connection.Error: return def coast_value_changed(self, checked): if checked: try: self.dc.set_drive_mode(1) except ip_connection.Error: return def full_brake_pressed(self): try: self.dc.full_brake() except ip_connection.Error: return def minimum_voltage_selected(self, value): try: self.dc.set_minimum_voltage(value) except ip_connection.Error: return def minimum_voltage_button_pressed(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(5000) qid.setIntMaximum(0xFFFF) qid.setIntStep(100) async_call(self.dc.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_voltage_selected) qid.setLabelText("Choose minimum motor voltage in mV.") qid.open() def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv/1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev/1000.0, 1) self.external_voltage_label.setText(ev_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv/1000.0, 1) self.minimum_voltage_label.setText(mv_str) def drive_mode_update(self, dm): if dm == 0: self.radio_mode_brake.setChecked(True) self.radio_mode_coast.setChecked(False) else: self.radio_mode_brake.setChecked(False) self.radio_mode_coast.setChecked(True) def current_consumption_update(self, cc): if cc >= 1000: cc_str = "%gA" % round(cc/1000.0, 1) else: cc_str = "%gmA" % cc self.current_label.setText(cc_str) def update_velocity(self, value): if value != self.speedometer.value(): self.speedometer.set_velocity(value) def get_velocity_async(self, velocity): if not self.velocity_slider.isSliderDown(): if velocity != self.velocity_slider.sliderPosition(): self.velocity_slider.setSliderPosition(velocity) self.velocity_spin.setValue(velocity) def get_acceleration_async(self, acceleration): if not self.acceleration_slider.isSliderDown(): if acceleration != self.acceleration_slider.sliderPosition(): self.acceleration_slider.setSliderPosition(acceleration) self.acceleration_spin.setValue(acceleration) def get_pwm_frequency_async(self, frequency): if not self.frequency_slider.isSliderDown(): if frequency != self.frequency_slider.sliderPosition(): self.frequency_slider.setSliderPosition(frequency) self.frequency_spin.setValue(frequency) def is_enabled_async(self, enabled): if enabled: self.enable_checkbox.setCheckState(Qt.Checked) else: self.enable_checkbox.setCheckState(Qt.Unchecked) def is_encoder_enabled_async(self, enabled): if enabled: self.enable_encoder_checkbox.setCheckState(Qt.Checked) else: self.enable_encoder_checkbox.setCheckState(Qt.Unchecked) def get_encoder_config_async(self, cpr): self.cpr_spinbox.setValue(cpr) def get_encoder_pid_config_async(self, pid_config): self.p_spinbox.setValue(pid_config.p) self.i_spinbox.setValue(pid_config.i) self.d_spinbox.setValue(pid_config.d) self.st_spinbox.setValue(pid_config.sample_time) def update_encoder(self): async_call(self.dc.get_encoder_config, None, self.get_encoder_config_async, self.increase_error_count) async_call(self.dc.get_encoder_pid_config, None, self.get_encoder_pid_config_async, self.increase_error_count) async_call(self.dc.is_encoder_enabled, None, self.is_encoder_enabled_async, self.increase_error_count) def update_start(self): async_call(self.dc.get_drive_mode, None, self.drive_mode_update, self.increase_error_count) async_call(self.dc.get_velocity, None, self.get_velocity_async, self.increase_error_count) async_call(self.dc.get_acceleration, None, self.get_acceleration_async, self.increase_error_count) async_call(self.dc.get_pwm_frequency, None, self.get_pwm_frequency_async, self.increase_error_count) async_call(self.dc.is_enabled, None, self.is_enabled_async, self.increase_error_count) # if self.version >= (2, 0, 1): # self.update_encoder() def update_data(self): async_call(self.dc.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count) async_call(self.dc.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count) async_call(self.dc.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count) async_call(self.dc.get_current_consumption, None, self.current_consumption_update, self.increase_error_count) def acceleration_slider_released(self): value = self.acceleration_slider.value() self.acceleration_spin.setValue(value) try: self.dc.set_acceleration(value) except ip_connection.Error: return def acceleration_spin_finished(self): value = self.acceleration_spin.value() self.acceleration_slider.setValue(value) try: self.dc.set_acceleration(value) except ip_connection.Error: return def velocity_slider_released(self): value = self.velocity_slider.value() self.velocity_spin.setValue(value) try: self.dc.set_velocity(value) except ip_connection.Error: return def velocity_spin_finished(self): value = self.velocity_spin.value() self.velocity_slider.setValue(value) try: self.dc.set_velocity(value) except ip_connection.Error: return def frequency_slider_released(self): value = self.frequency_slider.value() self.frequency_spin.setValue(value) try: self.dc.set_pwm_frequency(value) except ip_connection.Error: return def frequency_spin_finished(self): value = self.frequency_spin.value() self.frequency_slider.setValue(value) try: self.dc.set_pwm_frequency(value) except ip_connection.Error: return
def input_device_changed(self, index): self.ui.actionStart.setChecked(False) success, index = self.audiobackend.select_input_device(index) self.settings_dialog.comboBox_inputDevice.setCurrentIndex(index) if not success: # Note: the error message is a child of the settings dialog, so that # that dialog remains on top when the error message is closed error_message = QErrorMessage(self.settings_dialog) error_message.setWindowTitle("Input device error") error_message.showMessage( "Impossible to use the selected input device, reverting to the previous one" ) # reset the channels first_channel = self.audiobackend.get_current_first_channel() self.settings_dialog.comboBox_firstChannel.setCurrentIndex( first_channel) second_channel = self.audiobackend.get_current_second_channel() self.settings_dialog.comboBox_secondChannel.setCurrentIndex( second_channel) self.ui.actionStart.setChecked(True)