def __init__(self, project_manager: ProjectManager, is_tx: bool, backend_handler: BackendHandler = None, continuous_send_mode=False, parent=None): super().__init__(parent) self.ui = Ui_FormDeviceSettings() self.ui.setupUi(self) self.__device = None # type: VirtualDevice self.is_tx = is_tx self.is_rx = not is_tx if backend_handler is None: self.backend_handler = BackendHandler() else: self.backend_handler = backend_handler if self.is_rx: self.ui.spinBoxNRepeat.hide() self.ui.labelNRepeat.hide() else: self.ui.labelDCCorrection.hide() self.ui.checkBoxDCCorrection.hide() self.bw_sr_are_locked = settings.read("lock_bandwidth_sample_rate", True, bool) self.ui.cbDevice.clear() items = self.get_devices_for_combobox(continuous_send_mode) self.ui.cbDevice.addItems(items) self.bootstrap(project_manager.device_conf, enforce_default=True) self.ui.btnLockBWSR.setChecked(self.bw_sr_are_locked) self.on_btn_lock_bw_sr_clicked() ip_range = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" ip_regex = QRegExp("^" + ip_range + "\\." + ip_range + "\\." + ip_range + "\\." + ip_range + "$") self.ui.lineEditIP.setValidator(QRegExpValidator(ip_regex)) self.create_connects() self.sync_gain_sliders()
def __init__(self, project_manager: ProjectManager, is_tx: bool, backend_handler: BackendHandler = None, continuous_send_mode=False, parent=None): super().__init__(parent) self.ui = Ui_FormDeviceSettings() self.ui.setupUi(self) self.__device = None # type: VirtualDevice self.is_tx = is_tx self.is_rx = not is_tx if backend_handler is None: self.backend_handler = BackendHandler() else: self.backend_handler = backend_handler if self.is_rx: self.ui.spinBoxNRepeat.hide() self.ui.labelNRepeat.hide() self.bw_sr_are_locked = constants.SETTINGS.value("lock_bandwidth_sample_rate", True, bool) self.ui.cbDevice.clear() items = self.get_devices_for_combobox(continuous_send_mode) self.ui.cbDevice.addItems(items) self.bootstrap(project_manager.device_conf, enforce_default=True) self.ui.btnLockBWSR.setChecked(self.bw_sr_are_locked) self.on_btn_lock_bw_sr_clicked() ip_range = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" ip_regex = QRegExp("^" + ip_range + "\\." + ip_range + "\\." + ip_range + "\\." + ip_range + "$") self.ui.lineEditIP.setValidator(QRegExpValidator(ip_regex)) self.create_connects() self.sync_gain_sliders()
def __init__(self, project_manager: ProjectManager, is_tx: bool, backend_handler: BackendHandler = None, parent=None): super().__init__(parent) self.ui = Ui_FormDeviceSettings() self.ui.setupUi(self) self.is_tx = is_tx self.is_rx = not is_tx if backend_handler is None: self.backend_handler = BackendHandler() else: self.backend_handler = backend_handler if self.is_rx: self.ui.spinBoxNRepeat.hide() self.ui.labelNRepeat.hide() self.bw_sr_are_locked = constants.SETTINGS.value( "lock_bandwidth_sample_rate", True, bool) self.ui.spinBoxFreq.setValue(project_manager.device_conf["frequency"]) self.ui.spinBoxSampleRate.setValue( project_manager.device_conf["sample_rate"]) self.ui.spinBoxBandwidth.setValue( project_manager.device_conf["bandwidth"]) self.ui.spinBoxGain.setValue( project_manager.device_conf.get("gain", config.DEFAULT_GAIN)) self.ui.spinBoxIFGain.setValue( project_manager.device_conf.get("if_gain", config.DEFAULT_IF_GAIN)) self.ui.spinBoxBasebandGain.setValue( project_manager.device_conf.get("baseband_gain", config.DEFAULT_BB_GAIN)) self.ui.spinBoxFreqCorrection.setValue( project_manager.device_conf.get("freq_correction", config.DEFAULT_FREQ_CORRECTION)) self.ui.spinBoxNRepeat.setValue( constants.SETTINGS.value('num_sending_repeats', 1, type=int)) device = project_manager.device_conf["name"] self.ui.cbDevice.clear() items = self.get_devices_for_combobox() self.ui.cbDevice.addItems(items) if device in items: self.ui.cbDevice.setCurrentIndex(items.index(device)) dev_name = self.ui.cbDevice.currentText() self.set_device_ui_items_visibility(dev_name, adjust_gains=False) self.__device = None # type: VirtualDevice self.ui.btnLockBWSR.setChecked(self.bw_sr_are_locked) self.on_btn_lock_bw_sr_clicked() ip_range = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" ip_regex = QRegExp("^" + ip_range + "\\." + ip_range + "\\." + ip_range + "\\." + ip_range + "$") self.ui.lineEditIP.setValidator(QRegExpValidator(ip_regex)) if "gain" not in project_manager.device_conf: self.set_default_rf_gain() if "if_gain" not in project_manager.device_conf: self.set_default_if_gain() if "baseband_gain" not in project_manager.device_conf: self.set_default_bb_gain() self.create_connects() self.sync_gain_sliders()
class DeviceSettingsWidget(QWidget): selected_device_changed = pyqtSignal() gain_edited = pyqtSignal() device_parameters_changed = pyqtSignal(dict) def __init__(self, project_manager: ProjectManager, is_tx: bool, backend_handler: BackendHandler = None, parent=None): super().__init__(parent) self.ui = Ui_FormDeviceSettings() self.ui.setupUi(self) self.is_tx = is_tx self.is_rx = not is_tx if backend_handler is None: self.backend_handler = BackendHandler() else: self.backend_handler = backend_handler if self.is_rx: self.ui.spinBoxNRepeat.hide() self.ui.labelNRepeat.hide() self.bw_sr_are_locked = constants.SETTINGS.value( "lock_bandwidth_sample_rate", True, bool) self.ui.spinBoxFreq.setValue(project_manager.device_conf["frequency"]) self.ui.spinBoxSampleRate.setValue( project_manager.device_conf["sample_rate"]) self.ui.spinBoxBandwidth.setValue( project_manager.device_conf["bandwidth"]) self.ui.spinBoxGain.setValue( project_manager.device_conf.get("gain", config.DEFAULT_GAIN)) self.ui.spinBoxIFGain.setValue( project_manager.device_conf.get("if_gain", config.DEFAULT_IF_GAIN)) self.ui.spinBoxBasebandGain.setValue( project_manager.device_conf.get("baseband_gain", config.DEFAULT_BB_GAIN)) self.ui.spinBoxFreqCorrection.setValue( project_manager.device_conf.get("freq_correction", config.DEFAULT_FREQ_CORRECTION)) self.ui.spinBoxNRepeat.setValue( constants.SETTINGS.value('num_sending_repeats', 1, type=int)) device = project_manager.device_conf["name"] self.ui.cbDevice.clear() items = self.get_devices_for_combobox() self.ui.cbDevice.addItems(items) if device in items: self.ui.cbDevice.setCurrentIndex(items.index(device)) dev_name = self.ui.cbDevice.currentText() self.set_device_ui_items_visibility(dev_name, adjust_gains=False) self.__device = None # type: VirtualDevice self.ui.btnLockBWSR.setChecked(self.bw_sr_are_locked) self.on_btn_lock_bw_sr_clicked() ip_range = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" ip_regex = QRegExp("^" + ip_range + "\\." + ip_range + "\\." + ip_range + "\\." + ip_range + "$") self.ui.lineEditIP.setValidator(QRegExpValidator(ip_regex)) if "gain" not in project_manager.device_conf: self.set_default_rf_gain() if "if_gain" not in project_manager.device_conf: self.set_default_if_gain() if "baseband_gain" not in project_manager.device_conf: self.set_default_bb_gain() self.create_connects() self.sync_gain_sliders() @property def device(self) -> VirtualDevice: return self.__device @device.setter def device(self, value: VirtualDevice): self.__device = value @property def rx_tx_prefix(self) -> str: return "rx_" if self.is_rx else "tx_" @property def selected_device_conf(self) -> dict: device_name = self.ui.cbDevice.currentText() key = device_name if device_name in config.DEVICE_CONFIG.keys( ) else "Fallback" return config.DEVICE_CONFIG[key] def create_connects(self): self.ui.spinBoxFreq.editingFinished.connect( self.on_spinbox_frequency_editing_finished) self.ui.spinBoxSampleRate.editingFinished.connect( self.on_spinbox_sample_rate_editing_finished) self.ui.spinBoxGain.editingFinished.connect( self.on_spinbox_gain_editing_finished) self.ui.spinBoxGain.valueChanged.connect( self.on_spinbox_gain_value_changed) self.ui.sliderGain.valueChanged.connect( self.on_slider_gain_value_changed) self.ui.spinBoxIFGain.editingFinished.connect( self.on_spinbox_if_gain_editing_finished) self.ui.spinBoxIFGain.valueChanged.connect( self.on_spinbox_if_gain_value_changed) self.ui.sliderIFGain.valueChanged.connect( self.on_slider_if_gain_value_changed) self.ui.spinBoxBasebandGain.editingFinished.connect( self.on_spinbox_baseband_gain_editing_finished) self.ui.spinBoxBasebandGain.valueChanged.connect( self.on_spinbox_baseband_gain_value_changed) self.ui.sliderBasebandGain.valueChanged.connect( self.on_slider_baseband_gain_value_changed) self.ui.spinBoxBandwidth.editingFinished.connect( self.on_spinbox_bandwidth_editing_finished) self.ui.spinBoxPort.editingFinished.connect( self.on_spinbox_port_editing_finished) self.ui.lineEditIP.editingFinished.connect( self.on_line_edit_ip_editing_finished) self.ui.lineEditDeviceArgs.editingFinished.connect( self.on_line_edit_device_args_editing_finished) self.ui.comboBoxAntenna.currentIndexChanged.connect( self.on_combobox_antenna_current_index_changed) self.ui.comboBoxChannel.currentIndexChanged.connect( self.on_combobox_channel_current_index_changed) self.ui.spinBoxFreqCorrection.editingFinished.connect( self.on_spinbox_freq_correction_editing_finished) self.ui.comboBoxDirectSampling.currentIndexChanged.connect( self.on_combobox_direct_sampling_index_changed) self.ui.cbDevice.currentIndexChanged.connect( self.cb_device_current_index_changed) self.ui.spinBoxNRepeat.editingFinished.connect( self.on_num_repeats_changed) self.ui.btnLockBWSR.clicked.connect(self.on_btn_lock_bw_sr_clicked) def set_gain_defaults(self): self.set_default_rf_gain() self.set_default_if_gain() self.set_default_bb_gain() def set_default_rf_gain(self): conf = self.selected_device_conf prefix = self.rx_tx_prefix if prefix + "rf_gain" in conf: key = prefix + "rf_gain" gain = conf[key][int(median(range(len(conf[key]))))] self.ui.spinBoxGain.setValue(gain) def set_default_if_gain(self): conf = self.selected_device_conf prefix = self.rx_tx_prefix if prefix + "if_gain" in conf: key = prefix + "if_gain" if_gain = conf[key][int(median(range(len(conf[key]))))] self.ui.spinBoxIFGain.setValue(if_gain) def set_default_bb_gain(self): conf = self.selected_device_conf prefix = self.rx_tx_prefix if prefix + "baseband_gain" in conf: key = prefix + "baseband_gain" baseband_gain = conf[key][int(median(range(len(conf[key]))))] self.ui.spinBoxBasebandGain.setValue(baseband_gain) def sync_gain_sliders(self): self.ui.spinBoxGain.valueChanged.emit(self.ui.spinBoxGain.value()) self.ui.spinBoxIFGain.valueChanged.emit(self.ui.spinBoxIFGain.value()) self.ui.spinBoxBasebandGain.valueChanged.emit( self.ui.spinBoxBasebandGain.value()) def set_device_ui_items_visibility(self, device_name: str, adjust_gains=True): key = device_name if device_name in config.DEVICE_CONFIG.keys( ) else "Fallback" conf = config.DEVICE_CONFIG[key] key_ui_dev_param_map = { "center_freq": "Freq", "sample_rate": "SampleRate", "bandwidth": "Bandwidth" } for key, ui_item in key_ui_dev_param_map.items(): spinbox = getattr(self.ui, "spinBox" + ui_item) # type: QSpinBox label = getattr(self.ui, "label" + ui_item) # type: QLabel if key in conf: spinbox.setVisible(True) label.setVisible(True) if isinstance(conf[key], list): spinbox.allowed_values = conf[key] spinbox.setMinimum(min(conf[key])) spinbox.setMaximum(max(conf[key])) spinbox.setSingleStep(conf[key][1] - conf[key][0]) spinbox.auto_update_step_size = False else: spinbox.setMinimum(conf[key].start) spinbox.setMaximum(conf[key].stop) spinbox.auto_update_step_size = True spinbox.allowed_values = "all" spinbox.adjust_step() else: spinbox.setVisible(False) label.setVisible(False) self.ui.btnLockBWSR.setVisible("sample_rate" in conf and "bandwidth" in conf) if "freq_correction" in conf: self.ui.labelFreqCorrection.setVisible(True) self.ui.spinBoxFreqCorrection.setVisible(True) self.ui.spinBoxFreqCorrection.setMinimum( conf["freq_correction"].start) self.ui.spinBoxFreqCorrection.setMaximum( conf["freq_correction"].stop) self.ui.spinBoxFreqCorrection.setSingleStep( conf["freq_correction"].step) else: self.ui.labelFreqCorrection.setVisible(False) self.ui.spinBoxFreqCorrection.setVisible(False) if "direct_sampling" in conf: self.ui.labelDirectSampling.setVisible(True) self.ui.comboBoxDirectSampling.setVisible(True) items = [ self.ui.comboBoxDirectSampling.itemText(i) for i in range(self.ui.comboBoxDirectSampling.count()) ] if items != conf["direct_sampling"]: self.ui.comboBoxDirectSampling.clear() self.ui.comboBoxDirectSampling.addItems( conf["direct_sampling"]) else: self.ui.labelDirectSampling.setVisible(False) self.ui.comboBoxDirectSampling.setVisible(False) prefix = self.rx_tx_prefix key_ui_gain_map = { prefix + "rf_gain": "Gain", prefix + "if_gain": "IFGain", prefix + "baseband_gain": "BasebandGain" } for conf_key, ui_element in key_ui_gain_map.items(): getattr(self.ui, "label" + ui_element).setVisible(conf_key in conf) spinbox = getattr(self.ui, "spinBox" + ui_element) # type: QSpinBox slider = getattr(self.ui, "slider" + ui_element) # type: QSlider if conf_key in conf: gain_values = conf[conf_key] assert len(gain_values) >= 2 spinbox.setMinimum(gain_values[0]) spinbox.setMaximum(gain_values[-1]) if adjust_gains: spinbox.setValue(gain_values[len(gain_values) // 2]) spinbox.setSingleStep(gain_values[1] - gain_values[0]) spinbox.setVisible(True) slider.setMaximum(len(gain_values) - 1) else: spinbox.setVisible(False) slider.setVisible(False) getattr(self.ui, "slider" + ui_element).setVisible(conf_key in conf) key_ui_channel_ant_map = { prefix + "antenna": "Antenna", prefix + "channel": "Channel" } for conf_key, ui_element in key_ui_channel_ant_map.items(): getattr(self.ui, "label" + ui_element).setVisible(conf_key in conf) combobox = getattr(self.ui, "comboBox" + ui_element) # type: QComboBox if conf_key in conf: combobox.clear() combobox.addItems(conf[conf_key]) if conf_key + "_default_index" in conf: combobox.setCurrentIndex(conf[conf_key + "_default_index"]) combobox.setVisible(True) else: combobox.setVisible(False) self.ui.lineEditDeviceArgs.setVisible("device_args" in conf) self.ui.labelDeviceArgs.setVisible("device_args" in conf) self.ui.lineEditIP.setVisible("ip" in conf) self.ui.labelIP.setVisible("ip" in conf) self.ui.spinBoxPort.setVisible("port" in conf) self.ui.labelPort.setVisible("port" in conf) def get_devices_for_combobox(self): items = [] for device_name in self.backend_handler.DEVICE_NAMES: dev = self.backend_handler.device_backends[device_name.lower()] if self.is_tx and dev.is_enabled and dev.supports_tx: items.append(device_name) elif self.is_rx and dev.is_enabled and dev.supports_rx: items.append(device_name) if PluginManager().is_plugin_enabled("NetworkSDRInterface"): items.append(NetworkSDRInterfacePlugin.NETWORK_SDR_NAME) return items def set_bandwidth_status(self): if self.device is not None and self.device.backend != Backends.none: self.ui.spinBoxBandwidth.setEnabled( self.device.bandwidth_is_adjustable) self.ui.btnLockBWSR.setEnabled(self.device.bandwidth_is_adjustable) if not self.device.bandwidth_is_adjustable: self.bw_sr_are_locked = False self.ui.spinBoxBandwidth.setToolTip( self.tr( "Your driver of RTL-SDR does not support " "setting the bandwidth. " "If you need this feature, install a recent version.")) else: self.ui.spinBoxBandwidth.setToolTip("") self.bw_sr_are_locked = self.ui.btnLockBWSR.isChecked() def emit_editing_finished_signals(self): self.ui.spinBoxFreq.editingFinished.emit() self.ui.spinBoxBandwidth.editingFinished.emit() self.ui.spinBoxGain.editingFinished.emit() self.ui.spinBoxIFGain.editingFinished.emit() self.ui.spinBoxBasebandGain.editingFinished.emit() self.ui.spinBoxNRepeat.editingFinished.emit() self.ui.spinBoxSampleRate.editingFinished.emit() self.ui.spinBoxFreqCorrection.editingFinished.emit() self.ui.lineEditIP.editingFinished.emit() self.ui.spinBoxPort.editingFinished.emit() self.ui.lineEditDeviceArgs.editingFinished.emit() self.ui.comboBoxAntenna.currentIndexChanged.emit( self.ui.comboBoxAntenna.currentIndex()) self.ui.comboBoxChannel.currentIndexChanged.emit( self.ui.comboBoxChannel.currentIndex()) def emit_device_parameters_changed(self): settings = {"name": str(self.device.name)} for attrib in ("frequency", "sample_rate", "bandwidth", "gain", "if_gain", "baseband_gain", "freq_correction"): try: value = getattr(self.device, attrib, None) if value is not None: settings[attrib] = value except (ValueError, AttributeError): continue self.device_parameters_changed.emit(settings) @pyqtSlot() def on_btn_lock_bw_sr_clicked(self): self.bw_sr_are_locked = self.ui.btnLockBWSR.isChecked() constants.SETTINGS.setValue("lock_bandwidth_sample_rate", self.bw_sr_are_locked) if self.bw_sr_are_locked: self.ui.btnLockBWSR.setIcon(QIcon(":/icons/icons/lock.svg")) self.ui.spinBoxBandwidth.setValue( self.ui.spinBoxSampleRate.value()) self.ui.spinBoxBandwidth.editingFinished.emit() else: self.ui.btnLockBWSR.setIcon(QIcon(":/icons/icons/unlock.svg")) @pyqtSlot() def on_spinbox_sample_rate_editing_finished(self): self.device.sample_rate = self.ui.spinBoxSampleRate.value() if self.bw_sr_are_locked: self.ui.spinBoxBandwidth.setValue( self.ui.spinBoxSampleRate.value()) self.device.bandwidth = self.ui.spinBoxBandwidth.value() @pyqtSlot() def on_spinbox_frequency_editing_finished(self): self.device.frequency = self.ui.spinBoxFreq.value() @pyqtSlot() def on_spinbox_bandwidth_editing_finished(self): self.device.bandwidth = self.ui.spinBoxBandwidth.value() if self.bw_sr_are_locked: self.ui.spinBoxSampleRate.setValue( self.ui.spinBoxBandwidth.value()) self.device.sample_rate = self.ui.spinBoxSampleRate.value() @pyqtSlot() def on_line_edit_ip_editing_finished(self): self.device.ip = self.ui.lineEditIP.text() @pyqtSlot() def on_line_edit_device_args_editing_finished(self): self.device.device_args = self.ui.lineEditDeviceArgs.text() @pyqtSlot() def on_spinbox_port_editing_finished(self): self.device.port = self.ui.spinBoxPort.value() @pyqtSlot(int) def on_combobox_antenna_current_index_changed(self, index: int): self.device.antenna_index = index @pyqtSlot(int) def on_combobox_channel_current_index_changed(self, index: int): self.device.channel_index = index @pyqtSlot() def on_spinbox_freq_correction_editing_finished(self): self.device.freq_correction = self.ui.spinBoxFreqCorrection.value() @pyqtSlot(int) def on_combobox_direct_sampling_index_changed(self, index: int): self.device.direct_sampling_mode = index @pyqtSlot() def on_spinbox_gain_editing_finished(self): self.device.gain = self.ui.spinBoxGain.value() @pyqtSlot(int) def on_spinbox_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf try: self.ui.sliderGain.setValue(dev_conf[self.rx_tx_prefix + "rf_gain"].index(value)) except (ValueError, KeyError): pass @pyqtSlot(int) def on_slider_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf self.ui.spinBoxGain.setValue(dev_conf[self.rx_tx_prefix + "rf_gain"][value]) @pyqtSlot() def on_spinbox_if_gain_editing_finished(self): self.device.if_gain = self.ui.spinBoxIFGain.value() @pyqtSlot(int) def on_slider_if_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf self.ui.spinBoxIFGain.setValue(dev_conf[self.rx_tx_prefix + "if_gain"][value]) @pyqtSlot(int) def on_spinbox_if_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf try: self.ui.sliderIFGain.setValue(dev_conf[self.rx_tx_prefix + "if_gain"].index(value)) except (ValueError, KeyError): pass @pyqtSlot() def on_num_repeats_changed(self): self.device.num_sending_repeats = self.ui.spinBoxNRepeat.value() @pyqtSlot() def on_spinbox_baseband_gain_editing_finished(self): self.device.baseband_gain = self.ui.spinBoxBasebandGain.value() @pyqtSlot(int) def on_slider_baseband_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf self.ui.spinBoxBasebandGain.setValue(dev_conf[self.rx_tx_prefix + "baseband_gain"][value]) @pyqtSlot(int) def on_spinbox_baseband_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf try: self.ui.sliderBasebandGain.setValue( dev_conf[self.rx_tx_prefix + "baseband_gain"].index(value)) except (ValueError, KeyError): pass @pyqtSlot() def cb_device_current_index_changed(self): if self.device is not None: self.device.free_data() self.selected_device_changed.emit() dev_name = self.ui.cbDevice.currentText() self.set_device_ui_items_visibility(dev_name) self.set_gain_defaults() self.sync_gain_sliders() self.set_bandwidth_status()
class DeviceSettingsWidget(QWidget): selected_device_changed = pyqtSignal() gain_edited = pyqtSignal() device_parameters_changed = pyqtSignal(dict) def __init__(self, project_manager: ProjectManager, is_tx: bool, backend_handler: BackendHandler = None, continuous_send_mode=False, parent=None): super().__init__(parent) self.ui = Ui_FormDeviceSettings() self.ui.setupUi(self) self.__device = None # type: VirtualDevice self.is_tx = is_tx self.is_rx = not is_tx if backend_handler is None: self.backend_handler = BackendHandler() else: self.backend_handler = backend_handler if self.is_rx: self.ui.spinBoxNRepeat.hide() self.ui.labelNRepeat.hide() self.bw_sr_are_locked = constants.SETTINGS.value("lock_bandwidth_sample_rate", True, bool) self.ui.cbDevice.clear() items = self.get_devices_for_combobox(continuous_send_mode) self.ui.cbDevice.addItems(items) self.bootstrap(project_manager.device_conf, enforce_default=True) self.ui.btnLockBWSR.setChecked(self.bw_sr_are_locked) self.on_btn_lock_bw_sr_clicked() ip_range = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" ip_regex = QRegExp("^" + ip_range + "\\." + ip_range + "\\." + ip_range + "\\." + ip_range + "$") self.ui.lineEditIP.setValidator(QRegExpValidator(ip_regex)) self.create_connects() self.sync_gain_sliders() def bootstrap(self, conf_dict: dict, enforce_default=False): def set_val(ui_widget, key: str, default): try: value = conf_dict[key] except KeyError: value = default if enforce_default else None if value is not None: ui_widget.setValue(value) self.set_bandwidth_status() self.ui.cbDevice.setCurrentText(conf_dict.get("name", "")) dev_name = self.ui.cbDevice.currentText() self.set_device_ui_items_visibility(dev_name, adjust_gains=False) set_val(self.ui.spinBoxFreq, "frequency", config.DEFAULT_FREQUENCY) set_val(self.ui.spinBoxSampleRate, "sample_rate", config.DEFAULT_SAMPLE_RATE) set_val(self.ui.spinBoxBandwidth, "bandwidth", config.DEFAULT_BANDWIDTH) set_val(self.ui.spinBoxGain, self.rx_tx_prefix+"gain", config.DEFAULT_GAIN) set_val(self.ui.spinBoxIFGain, self.rx_tx_prefix+"if_gain", config.DEFAULT_IF_GAIN) set_val(self.ui.spinBoxBasebandGain, self.rx_tx_prefix+"baseband_gain", config.DEFAULT_BB_GAIN) set_val(self.ui.spinBoxFreqCorrection, "freq_correction", config.DEFAULT_FREQ_CORRECTION) set_val(self.ui.spinBoxNRepeat, "num_sending_repeats", constants.SETTINGS.value('num_sending_repeats', 1, type=int)) if self.rx_tx_prefix+"antenna_index" in conf_dict: self.ui.comboBoxAntenna.setCurrentIndex(conf_dict[self.rx_tx_prefix+"antenna_index"]) if self.rx_tx_prefix+"gain" not in conf_dict: self.set_default_rf_gain() if self.rx_tx_prefix+"if_gain" not in conf_dict: self.set_default_if_gain() if self.rx_tx_prefix+"baseband_gain" not in conf_dict: self.set_default_bb_gain() self.emit_editing_finished_signals() @property def device(self) -> VirtualDevice: return self.__device @device.setter def device(self, value: VirtualDevice): self.__device = value @property def rx_tx_prefix(self) -> str: return "rx_" if self.is_rx else "tx_" @property def selected_device_conf(self) -> dict: device_name = self.ui.cbDevice.currentText() key = device_name if device_name in config.DEVICE_CONFIG.keys() else "Fallback" return config.DEVICE_CONFIG[key] def create_connects(self): self.ui.spinBoxFreq.editingFinished.connect(self.on_spinbox_frequency_editing_finished) self.ui.spinBoxSampleRate.editingFinished.connect(self.on_spinbox_sample_rate_editing_finished) self.ui.spinBoxGain.editingFinished.connect(self.on_spinbox_gain_editing_finished) self.ui.spinBoxGain.valueChanged.connect(self.on_spinbox_gain_value_changed) self.ui.sliderGain.valueChanged.connect(self.on_slider_gain_value_changed) self.ui.spinBoxIFGain.editingFinished.connect(self.on_spinbox_if_gain_editing_finished) self.ui.spinBoxIFGain.valueChanged.connect(self.on_spinbox_if_gain_value_changed) self.ui.sliderIFGain.valueChanged.connect(self.on_slider_if_gain_value_changed) self.ui.spinBoxBasebandGain.editingFinished.connect(self.on_spinbox_baseband_gain_editing_finished) self.ui.spinBoxBasebandGain.valueChanged.connect(self.on_spinbox_baseband_gain_value_changed) self.ui.sliderBasebandGain.valueChanged.connect(self.on_slider_baseband_gain_value_changed) self.ui.spinBoxBandwidth.editingFinished.connect(self.on_spinbox_bandwidth_editing_finished) self.ui.spinBoxPort.editingFinished.connect(self.on_spinbox_port_editing_finished) self.ui.lineEditIP.editingFinished.connect(self.on_line_edit_ip_editing_finished) self.ui.comboBoxAntenna.currentIndexChanged.connect(self.on_combobox_antenna_current_index_changed) self.ui.comboBoxChannel.currentIndexChanged.connect(self.on_combobox_channel_current_index_changed) self.ui.spinBoxFreqCorrection.editingFinished.connect(self.on_spinbox_freq_correction_editing_finished) self.ui.comboBoxDirectSampling.currentIndexChanged.connect(self.on_combobox_direct_sampling_index_changed) self.ui.cbDevice.currentIndexChanged.connect(self.on_cb_device_current_index_changed) self.ui.spinBoxNRepeat.editingFinished.connect(self.on_num_repeats_changed) self.ui.btnLockBWSR.clicked.connect(self.on_btn_lock_bw_sr_clicked) self.ui.btnRefreshDeviceIdentifier.clicked.connect(self.on_btn_refresh_device_identifier_clicked) self.ui.comboBoxDeviceIdentifier.currentIndexChanged.connect(self.on_combo_box_device_identifier_current_index_changed) def set_gain_defaults(self): self.set_default_rf_gain() self.set_default_if_gain() self.set_default_bb_gain() def set_default_rf_gain(self): conf = self.selected_device_conf prefix = self.rx_tx_prefix if prefix + "rf_gain" in conf: key = prefix + "rf_gain" gain = conf[key][int(median(range(len(conf[key]))))] self.ui.spinBoxGain.setValue(gain) def set_default_if_gain(self): conf = self.selected_device_conf prefix = self.rx_tx_prefix if prefix + "if_gain" in conf: key = prefix + "if_gain" if_gain = conf[key][int(median(range(len(conf[key]))))] self.ui.spinBoxIFGain.setValue(if_gain) def set_default_bb_gain(self): conf = self.selected_device_conf prefix = self.rx_tx_prefix if prefix + "baseband_gain" in conf: key = prefix + "baseband_gain" baseband_gain = conf[key][int(median(range(len(conf[key]))))] self.ui.spinBoxBasebandGain.setValue(baseband_gain) def sync_gain_sliders(self): self.ui.spinBoxGain.valueChanged.emit(self.ui.spinBoxGain.value()) self.ui.spinBoxIFGain.valueChanged.emit(self.ui.spinBoxIFGain.value()) self.ui.spinBoxBasebandGain.valueChanged.emit(self.ui.spinBoxBasebandGain.value()) def set_device_ui_items_visibility(self, device_name: str, adjust_gains=True): key = device_name if device_name in config.DEVICE_CONFIG.keys() else "Fallback" conf = config.DEVICE_CONFIG[key] key_ui_dev_param_map = {"center_freq": "Freq", "sample_rate": "SampleRate", "bandwidth": "Bandwidth"} for key, ui_item in key_ui_dev_param_map.items(): spinbox = getattr(self.ui, "spinBox" + ui_item) # type: QSpinBox label = getattr(self.ui, "label" + ui_item) # type: QLabel if key in conf: spinbox.setVisible(True) label.setVisible(True) if isinstance(conf[key], list): spinbox.setMinimum(min(conf[key])) spinbox.setMaximum(max(conf[key])) spinbox.setSingleStep(conf[key][1] - conf[key][0]) spinbox.auto_update_step_size = False if "default_" + key in conf: spinbox.setValue(conf["default_"+key]) else: spinbox.setMinimum(conf[key].start) spinbox.setMaximum(conf[key].stop) spinbox.auto_update_step_size = True spinbox.adjust_step() else: spinbox.setVisible(False) label.setVisible(False) self.ui.btnLockBWSR.setVisible("sample_rate" in conf and "bandwidth" in conf) if "freq_correction" in conf: self.ui.labelFreqCorrection.setVisible(True) self.ui.spinBoxFreqCorrection.setVisible(True) self.ui.spinBoxFreqCorrection.setMinimum(conf["freq_correction"].start) self.ui.spinBoxFreqCorrection.setMaximum(conf["freq_correction"].stop) self.ui.spinBoxFreqCorrection.setSingleStep(conf["freq_correction"].step) else: self.ui.labelFreqCorrection.setVisible(False) self.ui.spinBoxFreqCorrection.setVisible(False) if "direct_sampling" in conf: self.ui.labelDirectSampling.setVisible(True) self.ui.comboBoxDirectSampling.setVisible(True) items = [self.ui.comboBoxDirectSampling.itemText(i) for i in range(self.ui.comboBoxDirectSampling.count())] if items != conf["direct_sampling"]: self.ui.comboBoxDirectSampling.clear() self.ui.comboBoxDirectSampling.addItems(conf["direct_sampling"]) else: self.ui.labelDirectSampling.setVisible(False) self.ui.comboBoxDirectSampling.setVisible(False) prefix = self.rx_tx_prefix key_ui_gain_map = {prefix + "rf_gain": "Gain", prefix + "if_gain": "IFGain", prefix + "baseband_gain": "BasebandGain"} for conf_key, ui_element in key_ui_gain_map.items(): getattr(self.ui, "label" + ui_element).setVisible(conf_key in conf) spinbox = getattr(self.ui, "spinBox" + ui_element) # type: QSpinBox slider = getattr(self.ui, "slider" + ui_element) # type: QSlider if conf_key in conf: gain_values = conf[conf_key] assert len(gain_values) >= 2 spinbox.setMinimum(gain_values[0]) spinbox.setMaximum(gain_values[-1]) if adjust_gains: spinbox.setValue(gain_values[len(gain_values) // 2]) spinbox.setSingleStep(gain_values[1] - gain_values[0]) spinbox.setVisible(True) slider.setMaximum(len(gain_values) - 1) else: spinbox.setVisible(False) slider.setVisible(False) getattr(self.ui, "slider" + ui_element).setVisible(conf_key in conf) key_ui_channel_ant_map = {prefix + "antenna": "Antenna", prefix + "channel": "Channel"} for conf_key, ui_element in key_ui_channel_ant_map.items(): getattr(self.ui, "label" + ui_element).setVisible(conf_key in conf) combobox = getattr(self.ui, "comboBox" + ui_element) # type: QComboBox if conf_key in conf: combobox.clear() combobox.addItems(conf[conf_key]) if conf_key + "_default_index" in conf: combobox.setCurrentIndex(conf[conf_key + "_default_index"]) combobox.setVisible(True) else: combobox.setVisible(False) multi_dev_support = hasattr(self.device, "has_multi_device_support") and self.device.has_multi_device_support self.ui.labelDeviceIdentifier.setVisible(multi_dev_support) self.ui.btnRefreshDeviceIdentifier.setVisible(multi_dev_support) self.ui.comboBoxDeviceIdentifier.setVisible(multi_dev_support) self.ui.lineEditIP.setVisible("ip" in conf) self.ui.labelIP.setVisible("ip" in conf) self.ui.spinBoxPort.setVisible("port" in conf) self.ui.labelPort.setVisible("port" in conf) def get_devices_for_combobox(self, continuous_send_mode): items = [] for device_name in self.backend_handler.DEVICE_NAMES: dev = self.backend_handler.device_backends[device_name.lower()] if self.is_tx and dev.is_enabled and dev.supports_tx: if not continuous_send_mode: items.append(device_name) elif dev.selected_backend != Backends.grc: items.append(device_name) elif self.is_rx and dev.is_enabled and dev.supports_rx: items.append(device_name) if PluginManager().is_plugin_enabled("NetworkSDRInterface"): items.append(NetworkSDRInterfacePlugin.NETWORK_SDR_NAME) return items def set_bandwidth_status(self): if hasattr(self, "device") and self.device is not None and self.device.backend != Backends.none: self.ui.spinBoxBandwidth.setEnabled(self.device.bandwidth_is_adjustable) self.ui.btnLockBWSR.setEnabled(self.device.bandwidth_is_adjustable) if not self.device.bandwidth_is_adjustable: self.bw_sr_are_locked = False self.ui.spinBoxBandwidth.setToolTip(self.tr("Your driver of RTL-SDR does not support " "setting the bandwidth. " "If you need this feature, install a recent version.")) else: self.ui.spinBoxBandwidth.setToolTip("") self.bw_sr_are_locked = self.ui.btnLockBWSR.isChecked() def emit_editing_finished_signals(self): self.ui.spinBoxFreq.editingFinished.emit() self.ui.spinBoxBandwidth.editingFinished.emit() self.ui.spinBoxGain.editingFinished.emit() self.ui.spinBoxIFGain.editingFinished.emit() self.ui.spinBoxBasebandGain.editingFinished.emit() self.ui.spinBoxNRepeat.editingFinished.emit() self.ui.spinBoxSampleRate.editingFinished.emit() self.ui.spinBoxFreqCorrection.editingFinished.emit() self.ui.lineEditIP.editingFinished.emit() self.ui.spinBoxPort.editingFinished.emit() self.ui.comboBoxAntenna.currentIndexChanged.emit(self.ui.comboBoxAntenna.currentIndex()) self.ui.comboBoxChannel.currentIndexChanged.emit(self.ui.comboBoxChannel.currentIndex()) def emit_device_parameters_changed(self): settings = {"name": str(self.device.name)} for attrib in ("frequency", "sample_rate", "bandwidth", "gain", "if_gain", "baseband_gain", "freq_correction", "antenna_index", "num_sending_repeats"): try: value = getattr(self.device, attrib, None) if value is not None: if "gain" in attrib or attrib == "antenna_index": attrib = self.rx_tx_prefix + attrib settings[attrib] = value except (ValueError, AttributeError): continue self.device_parameters_changed.emit(settings) @pyqtSlot() def on_btn_lock_bw_sr_clicked(self): self.bw_sr_are_locked = self.ui.btnLockBWSR.isChecked() constants.SETTINGS.setValue("lock_bandwidth_sample_rate", self.bw_sr_are_locked) if self.bw_sr_are_locked: self.ui.btnLockBWSR.setIcon(QIcon(":/icons/icons/lock.svg")) self.ui.spinBoxBandwidth.setValue(self.ui.spinBoxSampleRate.value()) self.ui.spinBoxBandwidth.editingFinished.emit() else: self.ui.btnLockBWSR.setIcon(QIcon(":/icons/icons/unlock.svg")) @pyqtSlot() def on_spinbox_sample_rate_editing_finished(self): self.device.sample_rate = self.ui.spinBoxSampleRate.value() if self.bw_sr_are_locked: self.ui.spinBoxBandwidth.setValue(self.ui.spinBoxSampleRate.value()) self.device.bandwidth = self.ui.spinBoxBandwidth.value() @pyqtSlot() def on_spinbox_frequency_editing_finished(self): self.device.frequency = self.ui.spinBoxFreq.value() @pyqtSlot() def on_spinbox_bandwidth_editing_finished(self): self.device.bandwidth = self.ui.spinBoxBandwidth.value() if self.bw_sr_are_locked: self.ui.spinBoxSampleRate.setValue(self.ui.spinBoxBandwidth.value()) self.device.sample_rate = self.ui.spinBoxSampleRate.value() @pyqtSlot() def on_line_edit_ip_editing_finished(self): self.device.ip = self.ui.lineEditIP.text() @pyqtSlot() def on_spinbox_port_editing_finished(self): self.device.port = self.ui.spinBoxPort.value() @pyqtSlot(int) def on_combobox_antenna_current_index_changed(self, index: int): self.device.antenna_index = index @pyqtSlot(int) def on_combobox_channel_current_index_changed(self, index: int): self.device.channel_index = index @pyqtSlot() def on_spinbox_freq_correction_editing_finished(self): self.device.freq_correction = self.ui.spinBoxFreqCorrection.value() @pyqtSlot(int) def on_combobox_direct_sampling_index_changed(self, index: int): self.device.direct_sampling_mode = index @pyqtSlot() def on_spinbox_gain_editing_finished(self): self.device.gain = self.ui.spinBoxGain.value() @pyqtSlot(int) def on_spinbox_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf try: self.ui.sliderGain.setValue(dev_conf[self.rx_tx_prefix + "rf_gain"].index(value)) except (ValueError, KeyError): pass @pyqtSlot(int) def on_slider_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf self.ui.spinBoxGain.setValue(dev_conf[self.rx_tx_prefix + "rf_gain"][value]) @pyqtSlot() def on_spinbox_if_gain_editing_finished(self): self.device.if_gain = self.ui.spinBoxIFGain.value() @pyqtSlot(int) def on_slider_if_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf self.ui.spinBoxIFGain.setValue(dev_conf[self.rx_tx_prefix + "if_gain"][value]) @pyqtSlot(int) def on_spinbox_if_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf try: self.ui.sliderIFGain.setValue(dev_conf[self.rx_tx_prefix + "if_gain"].index(value)) except (ValueError, KeyError): pass @pyqtSlot() def on_num_repeats_changed(self): self.device.num_sending_repeats = self.ui.spinBoxNRepeat.value() @pyqtSlot() def on_spinbox_baseband_gain_editing_finished(self): self.device.baseband_gain = self.ui.spinBoxBasebandGain.value() @pyqtSlot(int) def on_slider_baseband_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf self.ui.spinBoxBasebandGain.setValue(dev_conf[self.rx_tx_prefix + "baseband_gain"][value]) @pyqtSlot(int) def on_spinbox_baseband_gain_value_changed(self, value: int): dev_conf = self.selected_device_conf try: self.ui.sliderBasebandGain.setValue(dev_conf[self.rx_tx_prefix + "baseband_gain"].index(value)) except (ValueError, KeyError): pass @pyqtSlot() def on_cb_device_current_index_changed(self): if self.device is not None: self.device.free_data() # Here init_device of dialogs gets called self.selected_device_changed.emit() dev_name = self.ui.cbDevice.currentText() self.set_device_ui_items_visibility(dev_name) self.set_gain_defaults() self.sync_gain_sliders() self.set_bandwidth_status() self.ui.comboBoxDeviceIdentifier.clear() @pyqtSlot() def on_btn_refresh_device_identifier_clicked(self): if self.device is None: return self.ui.comboBoxDeviceIdentifier.clear() self.ui.comboBoxDeviceIdentifier.addItems(self.device.get_device_list()) @pyqtSlot() def on_combo_box_device_identifier_current_index_changed(self): if self.device is not None: self.device.device_serial = self.ui.comboBoxDeviceIdentifier.currentText() self.device.device_number = self.ui.comboBoxDeviceIdentifier.currentIndex()