MainCode/adalm1000_logger.py aktualisiert

Initializing new session...
Found 2 device(s) in session
Device error: Read error: No samples received
Device error: Read error: No samples received

close to working
This commit is contained in:
Jan 2025-08-06 16:21:19 +02:00
parent d59e75cad4
commit fc0e7329a4

View File

@ -17,6 +17,21 @@ from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QH
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtSlot, QObject, QThread from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtSlot, QObject, QThread
from PyQt5 import sip from PyQt5 import sip
import pysmu import pysmu
import pysmu.libsmu
from pysmu.exceptions import SessionError
class PatchedSession(pysmu.Session):
def __init__(self, ignore_dataflow=False, queue_size=0):
try:
super().__init__(ignore_dataflow=ignore_dataflow, queue_size=queue_size)
except SessionError as e:
if "failed scanning and/or adding all supported devices" in str(e):
print("⚠️ Ignored add_all() busy-device error, continuing...")
# The parent __init__ still runs and creates a session object
# We'll manually add devices later in init_device()
else:
raise
class DeviceDisconnectedError(Exception): class DeviceDisconnectedError(Exception):
pass pass
@ -972,53 +987,68 @@ class BatteryTester(QMainWindow):
self.main_layout.addWidget(self.canvas, 1) self.main_layout.addWidget(self.canvas, 1)
def init_device(self): def init_device(self):
"""Initialize ADALM1000 with proper device selection and session handling""" """Initialize ADALM1000 with proper permission handling"""
try: try:
# Clean up existing session # Clean up previous session if exists
if hasattr(self, 'session'): if hasattr(self, 'session'):
try: try:
self.session.end() self.session.end()
del self.session
except Exception as e: except Exception as e:
print(f"Error cleaning up session: {e}") print(f"Session cleanup error: {e}")
del self.session
time.sleep(0.5) # Brief pause for USB re-enumeration # Debug USB devices
print("Checking USB devices...")
usb_info = os.popen("lsusb -d 064b:784c -v").read()
print(usb_info)
# Initialize new session # Check if devices are present
self.session = pysmu.Session(ignore_dataflow=True, queue_size=10000) if "064b:784c" not in usb_info:
if not self.session.devices:
raise DeviceDisconnectedError("No ADALM1000 devices detected") raise DeviceDisconnectedError("No ADALM1000 devices detected")
# Populate device selector # Initialize new session with permission handling
self.device_combo.clear() print("Initializing new session...")
for dev in self.session.devices: try:
self.device_combo.addItem(dev.serial) # First try with normal permissions
self.session = pysmu.Session(ignore_dataflow=True, queue_size=10000)
except (OSError, pysmu.exceptions.SessionError) as e:
if "permission" in str(e).lower() or "not permitted" in str(e):
print("Permission error detected - requesting elevated privileges")
self.request_usb_permissions()
# Try again after permission request
self.session = pysmu.Session(ignore_dataflow=True, queue_size=10000)
else:
raise
# Select first device by default # Get and store available devices _einmal_
self.dev = self.session.devices[0] self.device_list = list(self.session.devices)
self.device_combo.setCurrentIndex(0) print(f"Found {len(self.device_list)} device(s) in session")
# Configure channels if not self.device_list:
raise DeviceDisconnectedError("No ADALM1000 devices available")
# Use the first available device
self.dev = self.device_list[0]
# Configure device
self.dev.channels['A'].mode = pysmu.Mode.HI_Z self.dev.channels['A'].mode = pysmu.Mode.HI_Z
self.dev.channels['B'].mode = pysmu.Mode.HI_Z self.dev.channels['B'].mode = pysmu.Mode.HI_Z
self.dev.channels['A'].constant(0) self.dev.channels['A'].constant(0)
self.dev.channels['B'].constant(0) self.dev.channels['B'].constant(0)
# Start session for the selected device # Start session
device_index = self.session.devices.index(self.dev) self.session.start(0)
self.session.start(device_index) self.session_active = True
# Update UI # Update UI
self.status_light.setStyleSheet("background-color: green; border-radius: 10px;") self.status_light.setStyleSheet("background-color: green; border-radius: 10px;")
self.connection_label.setText(f"Connected: {self.dev.serial}") self.connection_label.setText(f"Connected: {self.dev.serial}")
self.status_bar.showMessage(f"Ready - Device {self.dev.serial}") self.device_combo.clear()
self.session_active = True self.device_combo.addItem(self.dev.serial)
self.start_button.setEnabled(True)
# Start measurement thread # Start measurement thread
if hasattr(self, 'measurement_thread'): if hasattr(self, 'measurement_thread'):
self.measurement_thread.stop() self.measurement_thread.stop()
self.measurement_thread.wait(500)
self.measurement_thread = MeasurementThread(self.dev, self.interval) self.measurement_thread = MeasurementThread(self.dev, self.interval)
self.measurement_thread.update_signal.connect(self.update_measurements) self.measurement_thread.update_signal.connect(self.update_measurements)
@ -1026,11 +1056,84 @@ class BatteryTester(QMainWindow):
self.measurement_thread.start() self.measurement_thread.start()
except Exception as e: except Exception as e:
print(f"INIT ERROR DETAILS: {str(e)}")
self.handle_device_error(str(e)) self.handle_device_error(str(e))
def request_usb_permissions(self):
"""Handle USB permission issues with user interaction"""
msg = QMessageBox(self)
msg.setIcon(QMessageBox.Critical)
msg.setWindowTitle("USB Permission Required")
msg.setText("Permission needed to access ADALM1000 devices")
msg.setInformativeText(
"The application needs elevated privileges to access USB devices.\n\n"
"Please choose an option:"
)
# Add buttons
sudo_button = msg.addButton("Run as Administrator", QMessageBox.ActionRole)
udev_button = msg.addButton("Fix Permissions", QMessageBox.ActionRole)
cancel_button = msg.addButton(QMessageBox.Cancel)
msg.exec_()
if msg.clickedButton() == sudo_button:
# Restart with sudo
QMessageBox.information(self, "Restarting",
"The application will restart with administrator privileges")
args = sys.argv[:]
args.insert(0, sys.executable)
os.execvp("sudo", ["sudo"] + args)
elif msg.clickedButton() == udev_button:
# Create udev rule
rule_content = (
'# ADALM1000 USB permissions\n'
'SUBSYSTEM=="usb", ATTR{idVendor}=="064b", ATTR{idProduct}=="784c", MODE="0666"\n'
)
try:
# Try to create udev rule
rule_path = "/etc/udev/rules.d/52-adalm1000.rules"
with open(rule_path, "w") as f:
f.write(rule_content)
# Apply rules
os.system("sudo udevadm control --reload-rules")
os.system("sudo udevadm trigger")
QMessageBox.information(self, "Permissions Fixed",
"USB permissions configured. Please reconnect devices.")
except Exception as e:
QMessageBox.critical(self, "Error",
f"Failed to set permissions: {str(e)}\n\n"
"Please run these commands manually:\n\n"
f"echo '{rule_content}' | sudo tee {rule_path}\n"
"sudo udevadm control --reload-rules\n"
"sudo udevadm trigger")
def manual_device_init(self):
"""Manual device initialization workaround"""
try:
# Simulate device detection
self.device_combo.clear()
self.device_combo.addItem("ADALM1000-1 (Simulated)")
self.device_combo.addItem("ADALM1000-2 (Simulated)")
# Mock connection
self.status_light.setStyleSheet("background-color: orange; border-radius: 10px;")
self.connection_label.setText("Simulated Devices")
self.session_active = True
self.start_button.setEnabled(True)
QMessageBox.warning(self, "Simulation Mode",
"Using simulated devices - real hardware not detected")
except Exception as e:
print(f"Manual init failed: {e}")
def change_device(self, index): def change_device(self, index):
"""Safely switch to another ADALM1000 device""" """Safely switch to another ADALM1000 device"""
if not self.session_active or index < 0 or index >= len(self.session.devices): if not self.session_active or index < 0 or index >= len(self.device_list):
return return
try: try:
@ -1043,7 +1146,7 @@ class BatteryTester(QMainWindow):
self.measurement_thread.wait(500) self.measurement_thread.wait(500)
# Switch to new device # Switch to new device
self.dev = self.session.devices[index] self.dev = self.device_list[index]
# Reconfigure channels # Reconfigure channels
self.dev.channels['A'].mode = pysmu.Mode.HI_Z self.dev.channels['A'].mode = pysmu.Mode.HI_Z
@ -1052,8 +1155,11 @@ class BatteryTester(QMainWindow):
self.dev.channels['B'].constant(0) self.dev.channels['B'].constant(0)
# Restart session for new device # Restart session for new device
device_index = self.session.devices.index(self.dev) try:
self.session.start(device_index) self.session.stop()
except Exception:
pass
self.session.start(index)
# Update UI # Update UI
self.device_combo.setCurrentIndex(index) self.device_combo.setCurrentIndex(index)
@ -2198,7 +2304,7 @@ class BatteryTester(QMainWindow):
try: try:
# Reinitialize session # Reinitialize session
self.session = pysmu.Session(ignore_dataflow=True, queue_size=10000) self.session = PatchedSession(ignore_dataflow=True, queue_size=10000)
if not self.session.devices: if not self.session.devices:
raise DeviceDisconnectedError("No devices available") raise DeviceDisconnectedError("No devices available")
@ -2235,8 +2341,8 @@ class BatteryTester(QMainWindow):
# Restart measurement # Restart measurement
self.measurement_thread = MeasurementThread(self.dev, self.interval) self.measurement_thread = MeasurementThread(self.dev, self.interval)
self.measurement_thread.update_signal.connect(self.update_measurements) self.measurement_thread.update_signal.connect(lambda v, c, t, s: self.update_measurements(v, c, t) if s == self.current_device_serial else None)
self.measurement_thread.error_signal.connect(self.handle_device_error) self.measurement_thread.error_signal.connect(lambda e, s: self.handle_device_error(e) if s == self.current_device_serial else None)
self.measurement_thread.start() self.measurement_thread.start()
except Exception as e: except Exception as e: