fdr1gui/fdr1gui.py
2025-04-07 08:47:02 +02:00

202 lines
7.2 KiB
Python

import sys
import glob
import serial
import re
import requests
import random
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QSizePolicy, QPushButton)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSize
import time
class UpdateWorker(QThread):
update_signal = pyqtSignal(int, int)
def __init__(self, block, serial_number, bench_id):
super().__init__()
self.block = block
self.serial_number = serial_number
self.bench_id = bench_id
self.position_value = 0
def run(self):
while True:
diameter_value = random.randint(0, 100)
self.position_value += 1
self.update_signal.emit(diameter_value, self.position_value)
self.sleep(1) # Sleep for 1 second
class BlockStackApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.check_usb_devices()
def initUI(self):
# Set up the layout
self.layout = QVBoxLayout()
self.layout.setSpacing(5) # Set space between widgets to 5 pixels
self.layout.setContentsMargins(5, 5, 5, 5) # Set margins around the layout to 5 pixels
# Align the layout to the left
self.layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# Set the layout to the QWidget
self.setLayout(self.layout)
self.setWindowTitle('462filament Bench GUI')
# Apply dark theme
self.setStyleSheet("""
QWidget {
background-color: #2E2E2E;
color: #FFFFFF;
height: 100px;
}
QLabel {
background-color: #4A4A4A;
border: 1px solid #5A5A5A;
padding: 2px;
margin: 2px;
height: 30px;
width: 250px;
}
QPushButton {
background-color: #5A5A5A;
border: 1px solid #6A6A6A;
padding: 2px;
margin: 2px;
height: 30px;
width: 100px;
}
""")
# Show the window maximized
self.showMaximized()
def check_usb_devices(self):
# Check each /dev/ttyUSB? device
for port in glob.glob('/dev/ttyUSB*'):
try:
with serial.Serial(port, 1000000, timeout=1) as ser:
ser.write(b'i') # Send the character 'i'
time.sleep(1) # Wait for 1 second to receive data
response = ser.read_all().decode('utf-8').strip()
serial_number = self.extract_serial_number(response)
if serial_number:
bench_id = self.get_bench_id(serial_number)
if bench_id:
block = self.add_block(serial_number, bench_id)
# Start a QThread for each block
self.worker = UpdateWorker(block, serial_number, bench_id)
self.worker.update_signal.connect(self.update_block)
self.worker.start()
except serial.SerialException as e:
print(f"Could not open port {port}: {e}")
def extract_serial_number(self, response):
# Extract the hexadecimal serial number using a regular expression
match = re.match(r"id:([0-9A-Fa-f]+)", response)
if match:
return match.group(1)
return None
def get_bench_id(self, serial_number):
# Make a request to the API to get the bench ID
url = f"http://462filament/api.php?data=benchid&serial={serial_number}"
try:
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return data.get("id")
except requests.RequestException as e:
print(f"Error making request to API: {e}")
return None
def add_block(self, serial_number, bench_id):
# Create a new block with three zones
block_widget = QWidget()
block_layout = QHBoxLayout()
block_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
LABEL_SIZE = QSize(250, 20)
BUTTON_SIZE = QSize(100, 25)
# Left zone
left_layout = QVBoxLayout()
data_label = QLabel(f"Est. weight: 0 g\nStop: at end")
bench_label = QLabel(f"Bench ID: {bench_id}")
bench_label.setFixedSize(LABEL_SIZE)
diameter_label = QLabel("Diameter: 0")
diameter_label.setFixedSize(LABEL_SIZE)
position_label = QLabel("Position: 0")
position_label.setFixedSize(LABEL_SIZE)
left_layout.addWidget(bench_label)
left_layout.addWidget(diameter_label)
left_layout.addWidget(position_label)
left_layout.addWidget(data_label)
# Center zone (placeholder for graph)
center_layout = QVBoxLayout()
graph_placeholder = QLabel("Graph Placeholder")
graph_placeholder.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
center_layout.addWidget(graph_placeholder)
# Right zone with buttons
right_layout = QHBoxLayout()
right_layout_1 = QVBoxLayout()
right_layout_2 = QVBoxLayout()
right_layout_3 = QVBoxLayout()
buttons = [
("Home", " "), ("Sleep", "a"), ("Down Right", "t"),
("Up Right", "y"), ("Down Left", "g"), ("Up Left", "h"),
("Start", "S"), ("Stop", "R"), ("Reset", "r"),
("Go Right", "1"), ("Go Left", "2")
]
btn_start = QPushButton(f"Start")
right_layout_1.addWidget(btn_start)
right_layout_1.addWidget(QPushButton(f"Reset"))
right_layout_1.addWidget(QPushButton(f"Stop"))
right_layout_1.addWidget(QPushButton(f"Home"))
right_layout_2.addWidget(QPushButton(f"Go Left"))
right_layout_2.addWidget(QPushButton(f""))
right_layout_2.addWidget(QPushButton(f"Go Right"))
right_layout_2.addWidget(QPushButton(f"Sleep"))
right_layout_3.addWidget(QPushButton(f"Down Left"))
right_layout_3.addWidget(QPushButton(f"Up Left"))
right_layout_3.addWidget(QPushButton(f"Down Right"))
right_layout_3.addWidget(QPushButton(f"Up Right"))
right_layout.addLayout(right_layout_1)
right_layout.addLayout(right_layout_2)
right_layout.addLayout(right_layout_3)
# Add zones to the block layout
block_layout.addLayout(left_layout)
block_layout.addLayout(center_layout)
block_layout.addLayout(right_layout)
block_widget.setLayout(block_layout)
self.layout.addWidget(block_widget)
# Store labels for updating
block_widget.diameter_label = diameter_label
block_widget.position_label = position_label
return block_widget
def update_block(self, diameter_value, position_value):
# Update the block with random value and incrementing position_value
worker = self.sender()
worker.block.diameter_label.setText(f"Diameter: {diameter_value}")
worker.block.position_label.setText(f"Position: {position_value}")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = BlockStackApp()
sys.exit(app.exec_())