dev ok - before class split
This commit is contained in:
parent
c82835cdb0
commit
73cf7cbf03
167
fdr1gui.py
167
fdr1gui.py
@ -5,16 +5,19 @@ import re
|
|||||||
import requests
|
import requests
|
||||||
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
|
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
|
||||||
QLabel, QSizePolicy, QPushButton)
|
QLabel, QSizePolicy, QPushButton)
|
||||||
|
from PyQt5.QtGui import QFont
|
||||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSize
|
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSize
|
||||||
import time
|
import time
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||||
|
|
||||||
class UpdateWorker(QThread):
|
class UpdateWorker(QThread):
|
||||||
update_signal = pyqtSignal(float, float, float, float)
|
update_signal = pyqtSignal(bool, float, float, float, float)
|
||||||
data_received = pyqtSignal(str)
|
data_received = pyqtSignal(str)
|
||||||
stop_signal = pyqtSignal()
|
stop_signal = pyqtSignal()
|
||||||
not_homed_signal = pyqtSignal()
|
not_homed_signal = pyqtSignal()
|
||||||
mode_signal = pyqtSignal(int)
|
mode_signal = pyqtSignal(int)
|
||||||
change_color_signal = pyqtSignal(str, str, str) # Signal to change button color with identifier
|
change_color_signal = pyqtSignal(str, str, str)
|
||||||
|
|
||||||
def __init__(self, serial_number, bench_id, port, block_id):
|
def __init__(self, serial_number, bench_id, port, block_id):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -23,7 +26,7 @@ class UpdateWorker(QThread):
|
|||||||
self.serial_number = serial_number
|
self.serial_number = serial_number
|
||||||
self.bench_id = bench_id
|
self.bench_id = bench_id
|
||||||
self.port = port
|
self.port = port
|
||||||
self.block_id = block_id # Unique identifier for the block
|
self.block_id = block_id
|
||||||
self.running = True
|
self.running = True
|
||||||
self.position_value = 0.0
|
self.position_value = 0.0
|
||||||
self.diameter_value = 0.0
|
self.diameter_value = 0.0
|
||||||
@ -33,12 +36,13 @@ class UpdateWorker(QThread):
|
|||||||
self.prepare_ok = False
|
self.prepare_ok = False
|
||||||
self.reset_flag = False
|
self.reset_flag = False
|
||||||
self.ignore_stop = False
|
self.ignore_stop = False
|
||||||
|
self.is_running = False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
with serial.Serial(self.port, 1000000, timeout=1) as ser:
|
with serial.Serial(self.port, 1000000, timeout=1) as ser:
|
||||||
ser.write(b'a') # Send the character 'F'
|
ser.write(b'a')
|
||||||
ser.write(b'F') # Send the character 'F
|
ser.write(b'F')
|
||||||
self.change_color_signal.emit(self.block_id, 'btn_home', "#A0A000")
|
self.change_color_signal.emit(self.block_id, 'btn_home', "#A0A000")
|
||||||
while self.running:
|
while self.running:
|
||||||
if ser.in_waiting > 0:
|
if ser.in_waiting > 0:
|
||||||
@ -64,8 +68,9 @@ class UpdateWorker(QThread):
|
|||||||
self.change_color_signal.emit(self.block_id, 'btn_prepare', "#0000FF")
|
self.change_color_signal.emit(self.block_id, 'btn_prepare', "#0000FF")
|
||||||
else:
|
else:
|
||||||
if data == '%STOP':
|
if data == '%STOP':
|
||||||
if not self.ignore_stop :
|
if not self.ignore_stop:
|
||||||
self.change_color_signal.emit(self.block_id, 'btn_start', "#A00000")
|
self.change_color_signal.emit(self.block_id, 'btn_start', "#A00000")
|
||||||
|
self.is_running = False
|
||||||
else:
|
else:
|
||||||
self.ignore_stop = False
|
self.ignore_stop = False
|
||||||
elif data == '$NOTHOMED':
|
elif data == '$NOTHOMED':
|
||||||
@ -74,7 +79,6 @@ class UpdateWorker(QThread):
|
|||||||
print(f"Error with port {self.port}: {e}")
|
print(f"Error with port {self.port}: {e}")
|
||||||
|
|
||||||
def parse_data(self, data):
|
def parse_data(self, data):
|
||||||
# Parse the data and update diameter_value and position_value
|
|
||||||
match = re.match(r"[#d]:([\d.-]+),p:([\d.-]+)", data)
|
match = re.match(r"[#d]:([\d.-]+),p:([\d.-]+)", data)
|
||||||
if match:
|
if match:
|
||||||
self.diameter_value = float(match.group(1))
|
self.diameter_value = float(match.group(1))
|
||||||
@ -83,10 +87,9 @@ class UpdateWorker(QThread):
|
|||||||
self.diameter_min = self.diameter_value
|
self.diameter_min = self.diameter_value
|
||||||
if self.diameter_value > self.diameter_max:
|
if self.diameter_value > self.diameter_max:
|
||||||
self.diameter_max = self.diameter_value
|
self.diameter_max = self.diameter_value
|
||||||
self.update_signal.emit(self.diameter_value, self.position_value, self.diameter_min, self.diameter_max)
|
self.update_signal.emit(self.is_running, self.diameter_value, self.position_value, self.diameter_min, self.diameter_max)
|
||||||
self.reset_flag = True
|
self.reset_flag = True
|
||||||
|
|
||||||
# Parse mode and position data
|
|
||||||
mode_match = re.match(r"#o:(\d+),l:(\d+),r:(\d+),c:(\d+)", data)
|
mode_match = re.match(r"#o:(\d+),l:(\d+),r:(\d+),c:(\d+)", data)
|
||||||
if mode_match:
|
if mode_match:
|
||||||
mode = int(mode_match.group(1))
|
mode = int(mode_match.group(1))
|
||||||
@ -126,6 +129,17 @@ class UpdateWorker(QThread):
|
|||||||
self.diameter_min = self.diameter_value
|
self.diameter_min = self.diameter_value
|
||||||
self.diameter_max = self.diameter_value
|
self.diameter_max = self.diameter_value
|
||||||
|
|
||||||
|
def start_running(self):
|
||||||
|
self.is_running = True
|
||||||
|
self.clear_graph()
|
||||||
|
|
||||||
|
def stop_running(self):
|
||||||
|
self.is_running = False
|
||||||
|
|
||||||
|
def clear_graph(self):
|
||||||
|
self.line.set_data([], [])
|
||||||
|
self.canvas.draw()
|
||||||
|
|
||||||
def add_block(self, serial_number, bench_id, port, block_id):
|
def add_block(self, serial_number, bench_id, port, block_id):
|
||||||
block_widget = QWidget()
|
block_widget = QWidget()
|
||||||
block_layout = QHBoxLayout()
|
block_layout = QHBoxLayout()
|
||||||
@ -133,14 +147,80 @@ class UpdateWorker(QThread):
|
|||||||
|
|
||||||
LABEL_SIZE = QSize(250, 20)
|
LABEL_SIZE = QSize(250, 20)
|
||||||
BUTTON_SIZE = QSize(100, 25)
|
BUTTON_SIZE = QSize(100, 25)
|
||||||
|
VALUE_SIZE = QSize(80, 25)
|
||||||
|
VALUEL_SIZE = QSize(25, 25)
|
||||||
|
|
||||||
|
monospaced_font = QFont("unexistent", 10)
|
||||||
|
monospaced_font.setStyleHint(QFont.Monospace)
|
||||||
|
|
||||||
left_layout = QVBoxLayout()
|
left_layout = QVBoxLayout()
|
||||||
data_label = QLabel("---")
|
data_label = QLabel("No API data")
|
||||||
|
data_label.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
||||||
bench_label = QLabel(f"Bench ID: {bench_id}")
|
bench_label = QLabel(f"Bench ID: {bench_id}")
|
||||||
|
bench_label.setAlignment(Qt.AlignCenter)
|
||||||
bench_label.setFixedSize(LABEL_SIZE)
|
bench_label.setFixedSize(LABEL_SIZE)
|
||||||
left_layout.addWidget(bench_label)
|
left_layout.addWidget(bench_label)
|
||||||
left_layout.addWidget(data_label)
|
left_layout.addWidget(data_label)
|
||||||
|
|
||||||
|
left2_layout = QHBoxLayout()
|
||||||
|
left2L_layout = QVBoxLayout()
|
||||||
|
left2V_layout = QVBoxLayout()
|
||||||
|
max_label = QLabel("2.000 ")
|
||||||
|
max_label.setFont(monospaced_font)
|
||||||
|
avg_label = QLabel("2.0000")
|
||||||
|
avg_label.setFont(monospaced_font)
|
||||||
|
cur_label = QLabel("2.000 ")
|
||||||
|
cur_label.setFont(monospaced_font)
|
||||||
|
len_label = QLabel("12345.00")
|
||||||
|
len_label.setFont(monospaced_font)
|
||||||
|
wht_label = QLabel("12.345")
|
||||||
|
wht_label.setFont(monospaced_font)
|
||||||
|
min_label = QLabel("2.000 ")
|
||||||
|
min_label.setFont(monospaced_font)
|
||||||
|
maxL_label = QLabel("∨")
|
||||||
|
avgL_label = QLabel("⌀̄")
|
||||||
|
curL_label = QLabel("⌀")
|
||||||
|
lenL_label = QLabel("L")
|
||||||
|
whtL_label = QLabel("M")
|
||||||
|
minL_label = QLabel("∧")
|
||||||
|
avg_label.setAlignment(Qt.AlignRight)
|
||||||
|
max_label.setAlignment(Qt.AlignRight)
|
||||||
|
cur_label.setAlignment(Qt.AlignRight)
|
||||||
|
len_label.setAlignment(Qt.AlignRight)
|
||||||
|
wht_label.setAlignment(Qt.AlignRight)
|
||||||
|
min_label.setAlignment(Qt.AlignRight)
|
||||||
|
|
||||||
|
max_label.setFixedSize(VALUE_SIZE)
|
||||||
|
avg_label.setFixedSize(VALUE_SIZE)
|
||||||
|
cur_label.setFixedSize(VALUE_SIZE)
|
||||||
|
len_label.setFixedSize(VALUE_SIZE)
|
||||||
|
wht_label.setFixedSize(VALUE_SIZE)
|
||||||
|
min_label.setFixedSize(VALUE_SIZE)
|
||||||
|
|
||||||
|
maxL_label.setFixedSize(VALUEL_SIZE)
|
||||||
|
avgL_label.setFixedSize(VALUEL_SIZE)
|
||||||
|
curL_label.setFixedSize(VALUEL_SIZE)
|
||||||
|
lenL_label.setFixedSize(VALUEL_SIZE)
|
||||||
|
whtL_label.setFixedSize(VALUEL_SIZE)
|
||||||
|
minL_label.setFixedSize(VALUEL_SIZE)
|
||||||
|
|
||||||
|
left2V_layout.addWidget(max_label)
|
||||||
|
left2V_layout.addWidget(avg_label)
|
||||||
|
left2V_layout.addWidget(cur_label)
|
||||||
|
left2V_layout.addWidget(len_label)
|
||||||
|
left2V_layout.addWidget(wht_label)
|
||||||
|
left2V_layout.addWidget(min_label)
|
||||||
|
|
||||||
|
left2L_layout.addWidget(maxL_label)
|
||||||
|
left2L_layout.addWidget(avgL_label)
|
||||||
|
left2L_layout.addWidget(curL_label)
|
||||||
|
left2L_layout.addWidget(lenL_label)
|
||||||
|
left2L_layout.addWidget(whtL_label)
|
||||||
|
left2L_layout.addWidget(minL_label)
|
||||||
|
|
||||||
|
left2_layout.addLayout(left2L_layout)
|
||||||
|
left2_layout.addLayout(left2V_layout)
|
||||||
|
|
||||||
center_layout = QVBoxLayout()
|
center_layout = QVBoxLayout()
|
||||||
graph_placeholder = QLabel("Graph Placeholder")
|
graph_placeholder = QLabel("Graph Placeholder")
|
||||||
graph_placeholder.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
|
graph_placeholder.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
|
||||||
@ -157,10 +237,10 @@ class UpdateWorker(QThread):
|
|||||||
right_layout_1.addWidget(btn_prepare)
|
right_layout_1.addWidget(btn_prepare)
|
||||||
|
|
||||||
btn_start = QPushButton("Start")
|
btn_start = QPushButton("Start")
|
||||||
|
|
||||||
btn_start.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_start', "#00a000"))
|
btn_start.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_start', "#00a000"))
|
||||||
btn_start.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_prepare', "#5A5A5A"))
|
btn_start.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_prepare', "#5A5A5A"))
|
||||||
btn_start.clicked.connect(self.reset_diameter_limits)
|
btn_start.clicked.connect(self.reset_diameter_limits)
|
||||||
|
btn_start.clicked.connect(self.start_running)
|
||||||
btn_start.clicked.connect(lambda: self.send_command('S'))
|
btn_start.clicked.connect(lambda: self.send_command('S'))
|
||||||
right_layout_1.addWidget(btn_start)
|
right_layout_1.addWidget(btn_start)
|
||||||
|
|
||||||
@ -173,6 +253,7 @@ class UpdateWorker(QThread):
|
|||||||
btn_stop.clicked.connect(lambda: self.send_command('R'))
|
btn_stop.clicked.connect(lambda: self.send_command('R'))
|
||||||
btn_stop.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_start', "#a00000"))
|
btn_stop.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_start', "#a00000"))
|
||||||
btn_stop.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_prepare', "#5A5A5A"))
|
btn_stop.clicked.connect(lambda: self.change_color_signal.emit(self.block_id, 'btn_prepare', "#5A5A5A"))
|
||||||
|
btn_stop.clicked.connect(self.stop_running)
|
||||||
right_layout_1.addWidget(btn_stop)
|
right_layout_1.addWidget(btn_stop)
|
||||||
|
|
||||||
btn_sleep = QPushButton("Sleep")
|
btn_sleep = QPushButton("Sleep")
|
||||||
@ -215,6 +296,7 @@ class UpdateWorker(QThread):
|
|||||||
right_layout.addLayout(right_layout_3)
|
right_layout.addLayout(right_layout_3)
|
||||||
|
|
||||||
block_layout.addLayout(left_layout)
|
block_layout.addLayout(left_layout)
|
||||||
|
block_layout.addLayout(left2_layout)
|
||||||
block_layout.addLayout(center_layout)
|
block_layout.addLayout(center_layout)
|
||||||
block_layout.addLayout(right_layout)
|
block_layout.addLayout(right_layout)
|
||||||
|
|
||||||
@ -228,10 +310,28 @@ class UpdateWorker(QThread):
|
|||||||
block_widget.btn_prepare = btn_prepare
|
block_widget.btn_prepare = btn_prepare
|
||||||
block_widget.data_label = data_label
|
block_widget.data_label = data_label
|
||||||
|
|
||||||
|
block_widget.max_label = max_label
|
||||||
|
block_widget.avg_label = avg_label
|
||||||
|
block_widget.dia_label = cur_label
|
||||||
|
block_widget.len_label = len_label
|
||||||
|
block_widget.wht_label = wht_label
|
||||||
|
block_widget.min_label = min_label
|
||||||
|
|
||||||
|
# Create a Matplotlib figure and canvas for the graph
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
plt.subplots_adjust(left=0.0, right=0.9995, top=1, bottom=0.005)
|
||||||
|
ax.set_facecolor('#3a3a3a')
|
||||||
|
ax.set_xticks([]) # Hide x-axis values
|
||||||
|
ax.set_frame_on(True)
|
||||||
|
# ax.set_ylabel('Diameter (mm)') # Show y-axis label
|
||||||
|
self.line, = ax.plot([], [], '#ff5000', linewidth=0.5) # Set line width to 0.5
|
||||||
|
self.canvas = FigureCanvas(fig)
|
||||||
|
center_layout.addWidget(self.canvas)
|
||||||
|
|
||||||
return block_widget
|
return block_widget
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BlockStackApp(QWidget):
|
class BlockStackApp(QWidget):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -368,14 +468,43 @@ class BlockStackApp(QWidget):
|
|||||||
# Handle the data received from the serial port
|
# Handle the data received from the serial port
|
||||||
print(f"Data received: {data}")
|
print(f"Data received: {data}")
|
||||||
|
|
||||||
def update_block(self, diameter_value, position_value, diameter_min, diameter_max):
|
def update_block(self, is_running, diameter_value, position_value, diameter_min, diameter_max):
|
||||||
# Update the block with diameter_value and position_value
|
# Update the block with diameter_value and position_value
|
||||||
worker = self.sender()
|
worker = self.sender()
|
||||||
worker.block.data_label.setText(f"⌀: {diameter_min:.3f} < ⌀̄ {diameter_value:.3f} mm < {diameter_max:.3f}\n"
|
diameter_avg = 2.0000
|
||||||
f"L: {position_value/1000:.4f} m\n"
|
est_wgh = 1234
|
||||||
f"ρ: {1} g·cm¯³\n"
|
worker.block.min_label.setText(f"{diameter_min:.3f} ")
|
||||||
"\n- - -\n\n"
|
worker.block.max_label.setText(f"{diameter_max:.3f} ")
|
||||||
f"M: 0 g\nStop: at end")
|
worker.block.dia_label.setText(f"{diameter_value:.3f} ")
|
||||||
|
worker.block.avg_label.setText(f"{diameter_avg:.4f}")
|
||||||
|
worker.block.len_label.setText(f"{20000/1000:.4f}")
|
||||||
|
worker.block.wht_label.setText(f"{est_wgh/1000:.3f} ")
|
||||||
|
worker.block.data_label.setText(f"No API data")
|
||||||
|
|
||||||
|
# Update the graph with the new diameter value
|
||||||
|
if is_running:
|
||||||
|
self.update_graph(worker, diameter_value)
|
||||||
|
|
||||||
|
def update_graph(self, worker, diameter_value):
|
||||||
|
# Update the graph with the new diameter value
|
||||||
|
x_data = worker.line.get_xdata()
|
||||||
|
y_data = worker.line.get_ydata()
|
||||||
|
x_data = list(x_data)
|
||||||
|
y_data = list(y_data)
|
||||||
|
|
||||||
|
# Append new data point
|
||||||
|
x_data.append(len(x_data))
|
||||||
|
y_data.append(diameter_value)
|
||||||
|
|
||||||
|
# Update the line with the new data
|
||||||
|
worker.line.set_data(x_data, y_data)
|
||||||
|
|
||||||
|
# Rescale the graph
|
||||||
|
worker.line.axes.relim()
|
||||||
|
worker.line.axes.autoscale_view()
|
||||||
|
|
||||||
|
# Redraw the canvas
|
||||||
|
worker.canvas.draw()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user