diff options
Diffstat (limited to 'daq_system/daq_system/ui/add_device_dialog.py')
| -rw-r--r-- | daq_system/daq_system/ui/add_device_dialog.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/daq_system/daq_system/ui/add_device_dialog.py b/daq_system/daq_system/ui/add_device_dialog.py new file mode 100644 index 0000000..30d0016 --- /dev/null +++ b/daq_system/daq_system/ui/add_device_dialog.py @@ -0,0 +1,100 @@ +""" +ui/add_device_dialog.py — Dialog to add a new device at runtime. +""" + +from PyQt6.QtWidgets import ( + QDialog, QVBoxLayout, QFormLayout, QHBoxLayout, + QComboBox, QLineEdit, QSpinBox, QCheckBox, + QPushButton, QLabel, QMessageBox, +) + +from devices.device_registry import DeviceRegistry +from devices.analog_input import AnalogInputDevice +from devices.digital_io import DigitalIODevice +from devices.serial_device import SerialDevice + + +# Map display name -> (class, extra_kwargs_defaults) +_DEVICE_TYPES = { + "Analog Input — NI-DAQmx": (AnalogInputDevice, {"backend": "nidaqmx"}), + "Analog Input — Arduino": (AnalogInputDevice, {"backend": "arduino"}), + "Digital I/O — NI-DAQmx": (DigitalIODevice, {"backend": "nidaqmx"}), + "Digital I/O — Arduino": (DigitalIODevice, {"backend": "arduino"}), + "Serial / UART": (SerialDevice, {}), +} + + +class AddDeviceDialog(QDialog): + def __init__(self, registry: DeviceRegistry, parent=None): + super().__init__(parent) + self.registry = registry + self.created_device = None + self.setWindowTitle("Add Device") + self.setMinimumWidth(360) + self._build() + + def _build(self): + layout = QVBoxLayout(self) + form = QFormLayout() + + self._type_cb = QComboBox() + self._type_cb.addItems(list(_DEVICE_TYPES.keys())) + form.addRow("Device Type:", self._type_cb) + + self._id_edit = QLineEdit() + self._id_edit.setPlaceholderText("e.g. ai_1 / ser_0") + form.addRow("Device ID:", self._id_edit) + + self._ch_spin = QSpinBox() + self._ch_spin.setRange(1, 16) + self._ch_spin.setValue(4) + form.addRow("# Channels:", self._ch_spin) + + self._sim_chk = QCheckBox("Simulation mode (no hardware required)") + self._sim_chk.setChecked(True) + form.addRow(self._sim_chk) + + layout.addLayout(form) + + btns = QHBoxLayout() + btns.addStretch() + cancel = QPushButton("Cancel") + cancel.clicked.connect(self.reject) + add = QPushButton("Add Device") + add.setDefault(True) + add.setObjectName("applyButton") + add.clicked.connect(self._on_add) + btns.addWidget(cancel) + btns.addWidget(add) + layout.addLayout(btns) + + def _on_add(self): + label = self._type_cb.currentText() + cls, kw = _DEVICE_TYPES[label] + dev_id = self._id_edit.text().strip() + + if not dev_id: + base = kw.get("backend", "dev") + existing = {d.info.device_id for d in self.registry.all_instances()} + for i in range(100): + candidate = f"{base}_{i}" + if candidate not in existing: + dev_id = candidate + break + + if self.registry.get_instance(dev_id): + QMessageBox.warning(self, "Duplicate ID", + f"A device with ID '{dev_id}' already exists.") + return + + try: + dev = cls( + device_id=dev_id, + num_channels=self._ch_spin.value(), + simulate=self._sim_chk.isChecked(), + **kw, + ) + self.created_device = dev + self.accept() + except Exception as e: + QMessageBox.critical(self, "Error creating device", str(e)) |
