1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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))
|