Add connection checks

This commit is contained in:
CPD 2025-03-19 17:01:27 +01:00
parent d6442077e4
commit 0e61cd37c3
3 changed files with 89 additions and 13 deletions

View File

@ -138,6 +138,7 @@ class MainWindow(QMainWindow):
self.leddev_autoconnect()
# Measurement
self.idle_timer = None
self.measurement_timer = None
self.led_script = None
self.led_script_watcher = None
@ -150,6 +151,8 @@ class MainWindow(QMainWindow):
self.menuBar().m_file.addAction(self.a_open_about)
self.menuBar().m_file.addAction(self.a_open_help)
self.idle_start()
def set_status(self, msg):
self.statusBar().showMessage(msg)
@ -196,15 +199,26 @@ class MainWindow(QMainWindow):
# return TreeView(self)
# LED DEVICE MANAGEMENT
def leddev_connect(self, leddev_type, leddev_name):
def leddev_connect(self, leddev_type, leddev_name, fail_silently=False):
log.info(f"Connecting to LED device {leddev_name} ({leddev_type})")
self.leddev = ledd.connect_device(leddev_type, leddev_name)
try:
self.leddev = ledd.connect_device(leddev_type, leddev_name)
except Exception as e:
if not fail_silently:
QMessageBox.critical(self, "Connection failed", f"Failed to connect to '{leddev_name}', the following error occured: \n{e}")
return
AppConfig.MAIN_CFG.set("led_device_last.type", leddev_type)
AppConfig.MAIN_CFG.set("led_device_last.name", leddev_name)
self.leddev_connected()
def leddev_connected(self):
# Update the settings widget value
self.w_measurement_settings.set_value("device_led_controller", str(self.leddev))
led_name = self.leddev.get_led_name()
if not led_name: led_name = "Unknown"
self.w_measurement_settings.set_value("device_led_controller", self.leddev)
led_name = None
if self.leddev is not None:
led_name = self.leddev.get_led_name()
if not led_name:
led_name = "Unknown"
self.w_measurement_settings.set_value("device_led", led_name)
def leddev_autoconnect(self):
@ -212,7 +226,7 @@ class MainWindow(QMainWindow):
try:
leddev_type = AppConfig.MAIN_CFG.get("led_device_last.type")
leddev_name = AppConfig.MAIN_CFG.get("led_device_last.name")
self.leddev_connect(leddev_type, leddev_name)
self.leddev_connect(leddev_type, leddev_name, fail_silently=True)
except KeyError:
pass
except Exception as e:
@ -229,21 +243,40 @@ class MainWindow(QMainWindow):
leddev_type, leddev_name = device_dialog.get_selected()
self.leddev_connect(leddev_type, leddev_name)
def leddev_test_connection(self) -> bool:
if self.leddev is not None:
try:
self.leddev.test_connection()
return True
except ConnectionError as e:
QMessageBox.warning(self, "LED Controller Disconnected", f"Lost connection to the LED controller '{self.leddev}'")
self.leddev = None
self.leddev_connected()
return False
# VOLTAGE DEVICE MANAGEMENT
def vmdev_connect(self, vmdev_type, vmdev_name):
def vmdev_connect(self, vmdev_type, vmdev_name, fail_silently=False):
log.info(f"Connecting to voltage measurement device {vmdev_name} ({vmdev_type})")
self.vmdev = vmd.connect_device(vmdev_type, vmdev_name)
try:
self.vmdev = vmd.connect_device(vmdev_type, vmdev_name)
except Exception as e:
if not fail_silently:
QMessageBox.critical(self, "Connection failed", f"Failed to connect to '{leddev_name}', the following error occured: \n{e}")
return
AppConfig.MAIN_CFG.set("voltage_measurement_device_last.type", vmdev_type)
AppConfig.MAIN_CFG.set("voltage_measurement_device_last.name", vmdev_name)
self.vmdev_connected()
def vmdev_connected(self):
# Update the settings widget value
self.w_measurement_settings.set_value("device_voltage_measurement", str(self.vmdev))
self.w_measurement_settings.set_value("device_voltage_measurement", self.vmdev)
def vmdev_autoconnect(self):
if AppConfig.MAIN_CFG.get_or("voltage_measurement_device_auto_reconnect", False):
try:
vmdev_type = AppConfig.MAIN_CFG.get("voltage_measurement_device_last.type")
vmdev_name = AppConfig.MAIN_CFG.get("voltage_measurement_device_last.name")
self.vmdev_connect(vmdev_type, vmdev_name)
self.vmdev_connect(vmdev_type, vmdev_name, fail_silently=True)
except KeyError:
pass
except Exception as e:
@ -259,17 +292,47 @@ class MainWindow(QMainWindow):
vmdev_type, vmdev_name = device_dialog.get_selected()
self.vmdev_connect(vmdev_type, vmdev_name)
def vmdev_test_connection(self) -> bool:
if self.vmdev is not None:
try:
self.vmdev.test_connection()
return True
except ConnectionError as e:
QMessageBox.warning(self, "Voltage Measurement Device Disconnected", f"Lost connection to the voltage measurement device '{self.vmdev}'")
self.vmdev = None
self.vmdev_connected()
return False
# IDLE - NOT IN MEASUREMENT
# check if devices stayed connected
def idle_start(self):
self.idle_timer = QTimer(self)
self.idle_timer.timeout.connect(self.idle_update)
self.idle_timer.start(AppConfig.MAIN_CFG.get_or("idle_update_interval_s", 10)*1000)
def idle_update(self):
self.vmdev_test_connection()
self.leddev_test_connection()
def idle_stop(self):
self.idle_timer.stop()
self.idle_timer = None
# MEASUREMENT
def measure_start(self):
if self.vmdev is None:
self.vmdev_connect_from_dialog()
if self.vmdev is None:
raise ValueError("No measurement device selected")
raise RuntimeError("No measurement device selected")
if self.leddev is None:
self.leddev_connect_from_dialog()
if self.leddev is None:
raise ValueError("No led control device selected")
raise RuntimeError("No led control device selected")
self.idle_stop()
if not (self.vmdev_connected() and self.leddev_connected()):
raise RuntimeError(f"Can not start measurement, a device lost connection.")
name = self.w_measurement_settings.get_value("name")
script = self.w_measurement_settings.get_value("led_script")
@ -334,6 +397,7 @@ class MainWindow(QMainWindow):
self.data_queue,
auto_add_metadata,
))
# todo: error handling
self.proc_measure.start()
self.measurement_timer = QTimer(self)
self.measurement_timer.timeout.connect(self.measure_update)
@ -381,6 +445,7 @@ class MainWindow(QMainWindow):
self.w_measurement_settings.setEnabled(True)
self.w_metadata.setEnabled(True)
self.set_status("Ready")
self.idle_start()
def measure_update(self):
self.w_led_script_viewer.update_time(time.time())

View File

@ -30,4 +30,9 @@ class AppSettings(QWidget):
self.w_form.add_form_row("metadata_auto_add", "Auto-Add Metadata", True, QCheckBox(), "Automatically add measurement metadata to the data file.\nThis includes: device names, measurement mode, measurement interval, start and stop times, led script")
w_usb_switch_exe = FileSelection(filemode=QFileDialog.FileMode.ExistingFile)
self.w_form.add_form_row("power_switch_exe", "Power Switch Executable", "", w_usb_switch_exe, "Path to the USBSwitchCmd executable for the Cleware USB switch\nRequires a relaunch to take effect")
w_idle_dt = QSpinBox()
w_idle_dt.setMinimum(10)
w_idle_dt.setMaximum(200000)
w_idle_dt.setSingleStep(10)
self.w_form.add_form_row("idle_update_interval_s", "Device Connection Check Interval (s)", 30, w_plot_dt, "How often to check whether the devices are still connected.\nApplies only when not in a measurement.")

View File

@ -28,7 +28,13 @@ class DeviceSelection(QGroupBox):
def set_value(self, key, value):
key = key.replace("device_", "")
if key in self.devices_widgets:
self.devices_widgets[key].setText(value)
if value is None:
text = "N.C."
elif type(value) != str:
text = str(value)
else:
text = value
self.devices_widgets[key].setText(text)
else:
raise KeyError(f"Unknown device '{key}'")