diff --git a/src/nqrduck_autotm/controller.py b/src/nqrduck_autotm/controller.py
index 81a1e88..c2a1324 100644
--- a/src/nqrduck_autotm/controller.py
+++ b/src/nqrduck_autotm/controller.py
@@ -1,13 +1,14 @@
import logging
+import serial
from serial.tools.list_ports import comports
from nqrduck.module.module_controller import ModuleController
logger = logging.getLogger(__name__)
class AutoTMController(ModuleController):
-
+ BAUDRATE = 115200
- def find_devices(self):
+ def find_devices(self) -> None:
"""Scan for available serial devices and add them to the model as available devices. """
logger.debug("Scanning for available serial devices")
ports = comports()
@@ -15,3 +16,13 @@ class AutoTMController(ModuleController):
logger.debug("Found %s devices", len(self.module.model.available_devices))
for device in self.module.model.available_devices:
logger.debug("Found device: %s", device)
+
+ def connect(self, device : str) -> None:
+ """Connect to the specified device. """
+ logger.debug("Connecting to device %s", device)
+ try:
+ self.module.model.serial = serial.Serial(device, self.BAUDRATE, timeout=0.1)
+ logger.debug("Connected to device %s", device)
+ except serial.SerialException as e:
+ logger.error("Failed to connect to device %s", device)
+ logger.error(e)
diff --git a/src/nqrduck_autotm/model.py b/src/nqrduck_autotm/model.py
index 8db4226..50d485c 100644
--- a/src/nqrduck_autotm/model.py
+++ b/src/nqrduck_autotm/model.py
@@ -1,8 +1,10 @@
+import serial
from PyQt6.QtCore import pyqtSignal
from nqrduck.module.module_model import ModuleModel
class AutoTMModel(ModuleModel):
available_devices_changed = pyqtSignal(list)
+ serial_changed = pyqtSignal(serial.Serial)
@property
def available_devices(self):
@@ -12,3 +14,12 @@ class AutoTMModel(ModuleModel):
def available_devices(self, value):
self._available_devices = value
self.available_devices_changed.emit(value)
+
+ @property
+ def serial(self):
+ return self._serial
+
+ @serial.setter
+ def serial(self, value):
+ self._serial = value
+ self.serial_changed.emit(value)
diff --git a/src/nqrduck_autotm/resources/autotm_widget.ui b/src/nqrduck_autotm/resources/autotm_widget.ui
index e24edbe..44fe3b0 100644
--- a/src/nqrduck_autotm/resources/autotm_widget.ui
+++ b/src/nqrduck_autotm/resources/autotm_widget.ui
@@ -37,6 +37,9 @@
-
+
-
+
+
-
@@ -44,11 +47,8 @@
- -
-
-
-
-
+
Connect
@@ -61,6 +61,20 @@
+ -
+
+
+ Connected to:
+
+
+
+ -
+
+
+
+
+
+
-
@@ -168,7 +182,7 @@
0
0
273
- 255
+ 231
diff --git a/src/nqrduck_autotm/view.py b/src/nqrduck_autotm/view.py
index a513975..6d439ac 100644
--- a/src/nqrduck_autotm/view.py
+++ b/src/nqrduck_autotm/view.py
@@ -1,6 +1,8 @@
import logging
-from PyQt6.QtWidgets import QWidget
-from PyQt6.QtCore import pyqtSlot
+import serial
+from datetime import datetime
+from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout
+from PyQt6.QtCore import pyqtSlot, Qt
from nqrduck.module.module_view import ModuleView
from .widget import Ui_Form
@@ -16,16 +18,71 @@ class AutoTMView(ModuleView):
self._ui_form.setupUi(self)
self.widget = widget
+ # Disable the connectButton while no devices are selected
+ self._ui_form.connectButton.setDisabled(True)
+
# On clicking of the refresh button scan for available usb devices
self._ui_form.refreshButton.clicked.connect(self.module.controller.find_devices)
# Connect the available devices changed signal to the on_available_devices_changed slot
self.module.model.available_devices_changed.connect(self.on_available_devices_changed)
+ # Connect the serial changed signal to the on_serial_changed slot
+ self.module.model.serial_changed.connect(self.on_serial_changed)
+
+ # On clicking of the connect button call the connect method
+ self._ui_form.connectButton.clicked.connect(self.on_connect_button_clicked)
+
+ # Add a vertical layout to the info box
+ self._ui_form.scrollAreaWidgetContents.setLayout(QVBoxLayout())
+ self._ui_form.scrollAreaWidgetContents.layout().setAlignment(Qt.AlignmentFlag.AlignTop)
+
@pyqtSlot(list)
- def on_available_devices_changed(self, available_devices):
+ def on_available_devices_changed(self, available_devices : list) -> None:
"""Update the available devices list in the view. """
logger.debug("Updating available devices list")
self._ui_form.portBox.clear()
self._ui_form.portBox.addItems(available_devices)
- logger.debug("Updated available devices list")
\ No newline at end of file
+ # Enable the connectButton if there are available devices
+ if available_devices:
+ self._ui_form.connectButton.setEnabled(True)
+ else:
+ self._ui_form.connectButton.setEnabled(False)
+ logger.debug("Updated available devices list")
+
+ @pyqtSlot()
+ def on_connect_button_clicked(self) -> None:
+ """This method is called when the connect button is clicked.
+ It calls the connect method of the controller with the currently selected device.
+ """
+ logger.debug("Connect button clicked")
+ selected_device = self._ui_form.portBox.currentText()
+ self.module.controller.connect(selected_device)
+
+ @pyqtSlot(serial.Serial)
+ def on_serial_changed(self, serial : serial.Serial) -> None:
+ """Update the serial 'connectionLabel' according to the current serial connection.
+
+ Args:
+ serial (serial.Serial): The current serial connection."""
+ logger.debug("Updating serial connection label")
+ if serial.is_open:
+ self._ui_form.connectionLabel.setText(serial.port)
+ self.add_info_text("Connected to device %s" % serial.port)
+ else:
+ self._ui_form.connectionLabel.setText("Disconnected")
+ logger.debug("Updated serial connection label")
+
+ def add_info_text(self, text : str) -> None:
+ """ Adds text to the info text box.
+
+ Args:
+ text (str): Text to add to the info text box.
+ """
+ # Add a timestamp to the text
+ timestamp = datetime.now().strftime("%H:%M:%S")
+ text = "[%s] %s" % (timestamp, text)
+ text_label = QLabel(text)
+ text_label.setStyleSheet("font-size: 25px;")
+ self._ui_form.scrollAreaWidgetContents.layout().addWidget(text_label)
+ self._ui_form.scrollArea.verticalScrollBar().setValue(self._ui_form.scrollArea.verticalScrollBar().maximum())
\ No newline at end of file
diff --git a/src/nqrduck_autotm/widget.py b/src/nqrduck_autotm/widget.py
index 8027ca3..986183c 100644
--- a/src/nqrduck_autotm/widget.py
+++ b/src/nqrduck_autotm/widget.py
@@ -1,6 +1,6 @@
# Form implementation generated from reading ui file '../Modules/nqrduck-autotm/src/nqrduck_autotm/resources/autotm_widget.ui'
#
-# Created by: PyQt6 UI code generator 6.5.1
+# Created by: PyQt6 UI code generator 6.5.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
@@ -31,18 +31,25 @@ class Ui_Form(object):
self.verticalLayout_2.addWidget(self.label_2)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
- self.label = QtWidgets.QLabel(parent=Form)
- self.label.setObjectName("label")
- self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1)
self.portBox = QtWidgets.QComboBox(parent=Form)
self.portBox.setObjectName("portBox")
self.gridLayout_2.addWidget(self.portBox, 0, 1, 1, 1)
- self.pushButton = QtWidgets.QPushButton(parent=Form)
- self.pushButton.setObjectName("pushButton")
- self.gridLayout_2.addWidget(self.pushButton, 1, 1, 1, 1)
+ self.label = QtWidgets.QLabel(parent=Form)
+ self.label.setObjectName("label")
+ self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1)
+ self.connectButton = QtWidgets.QPushButton(parent=Form)
+ self.connectButton.setObjectName("connectButton")
+ self.gridLayout_2.addWidget(self.connectButton, 1, 1, 1, 1)
self.refreshButton = QtWidgets.QPushButton(parent=Form)
self.refreshButton.setObjectName("refreshButton")
self.gridLayout_2.addWidget(self.refreshButton, 1, 0, 1, 1)
+ self.label_10 = QtWidgets.QLabel(parent=Form)
+ self.label_10.setObjectName("label_10")
+ self.gridLayout_2.addWidget(self.label_10, 2, 0, 1, 1)
+ self.connectionLabel = QtWidgets.QLabel(parent=Form)
+ self.connectionLabel.setText("")
+ self.connectionLabel.setObjectName("connectionLabel")
+ self.gridLayout_2.addWidget(self.connectionLabel, 2, 1, 1, 1)
self.verticalLayout_2.addLayout(self.gridLayout_2)
self.label_3 = QtWidgets.QLabel(parent=Form)
font = QtGui.QFont()
@@ -99,7 +106,7 @@ class Ui_Form(object):
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
- self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 273, 255))
+ self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 273, 231))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.verticalLayout_2.addWidget(self.scrollArea)
@@ -125,8 +132,9 @@ class Ui_Form(object):
Form.setWindowTitle(_translate("Form", "Form"))
self.label_2.setText(_translate("Form", "Connection Settings:"))
self.label.setText(_translate("Form", "Port:"))
- self.pushButton.setText(_translate("Form", "Connect"))
+ self.connectButton.setText(_translate("Form", "Connect"))
self.refreshButton.setText(_translate("Form", "Refresh"))
+ self.label_10.setText(_translate("Form", "Connected to:"))
self.label_3.setText(_translate("Form", "T&M Type:"))
self.label_4.setText(_translate("Form", "Frequency Sweep:"))
self.label_8.setText(_translate("Form", "MHz"))