This commit is contained in:
Jonathan Roth 2025-04-14 12:27:23 +02:00
parent c90ea4cf85
commit 72856ace3c
3 changed files with 91 additions and 28 deletions

View File

@ -9,15 +9,15 @@ import math
from UpdateWorker import UpdateWorker
class BlockStackApp(QWidget):
def __init__(self):
def __init__(self, fullscreen):
super().__init__()
self.initUI()
self.initUI(fullscreen)
self.check_usb_devices()
self.update_count = 11
def initUI(self):
def initUI(self, fullscreen):
self.layout = QVBoxLayout()
self.layout.setSpacing(5)
self.layout.setContentsMargins(5, 5, 5, 5)
@ -50,7 +50,10 @@ class BlockStackApp(QWidget):
}
""")
self.showMaximized()
if fullscreen:
self.showFullScreen()
else:
self.showMaximized()
def check_usb_devices(self):
bench_list = []
@ -183,17 +186,24 @@ class BlockStackApp(QWidget):
worker.diameter_min = diameter_value
worker.diameter_max = diameter_value
worker.clear_graph()
worker.data_list.clear()
worker.reset_data = False
else:
worker.diameter_total += diameter_value
worker.diameter_total += diameter_value # to calc average diameter
worker.diameter_count += 1
if diameter_value < worker.diameter_min:
if diameter_value < worker.diameter_min: # process min/max
worker.diameter_min = diameter_value
if diameter_value > worker.diameter_max:
worker.diameter_max = diameter_value
worker.block.min_label.setText(f"{worker.diameter_min:.3f} ")
worker.block.max_label.setText(f"{worker.diameter_max:.3f} ")
# push data to memory for report
worker.data_list.append((position_value, diameter_value))
# push data to graph and update it
self.update_graph(worker, diameter_value)
# calculate and display average diameter

View File

@ -10,6 +10,9 @@ import matplotlib.pyplot as plt
import os
import struct
import requests
import subprocess
from datetime import datetime
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
class UpdateWorker(QThread):
@ -18,12 +21,13 @@ class UpdateWorker(QThread):
stop_signal = pyqtSignal()
mode_signal = pyqtSignal(int)
offset_signal = pyqtSignal(int)
apitimer_signal = pyqtSignal()
change_color_signal = pyqtSignal(str, str, str)
def __init__(self, serial_number, bench_id, port, block_id, main_app):
super().__init__()
print(f"id{bench_id} :\tport {port}")
print(f"id{bench_id} :\tserial {serial_number}")
print(f"id{bench_id}:\tport {port}")
print(f"id{bench_id}:\tserial {serial_number}")
self.block = self.add_block(serial_number, bench_id, port, block_id, main_app)
self.main_app = main_app # Store the reference to the BlockStackApp instance
self.serial_number = serial_number
@ -46,6 +50,8 @@ class UpdateWorker(QThread):
self.reset_data = False
self.homed = False
self.can_start = False
self.current_job = None
self.current_job = None
self.data_list = []
self.profile_data = {} # Dictionary to store profile data
@ -98,29 +104,61 @@ class UpdateWorker(QThread):
self.homed = False
self.change_color_signal.emit(self.block_id, 'btn_home', "#a0a000")
elif data == '$HOMED':
print(f"id{self.bench_id} :\tHoming ok")
# print(f"id{self.bench_id} :\tHoming ok")
self.homed = True
self.change_color_signal.emit(self.block_id, 'btn_home', "#5a5a5a")
except serial.SerialException as e:
print(f"Error with port {self.port}: {e}")
def save_data_to_file(self):
#FIXME: set name
#FIXME: add file header
#FIXME: compress file
#FIXME: upload to API
file_path = os.path.join("data", f"{self.bench_id}_data.txt")
# Ensure the directory exists
os.makedirs(os.path.dirname(file_path), exist_ok=True)
# format:
#
# #bench: FDR1-proto0
# #date: 20250224_232750
# #spool: R587
# #material: Enky PP Ortho V1-2106 20251007-00 N°7
# d:1.730,dm:1.730,dM:1.730,p:0.000,s:0.0,m:1500.0000,q:3,ap:0/3598
# d:1.730,dm:1.730,dM:1.730,p:2.291,s:0.0,m:1504.5000,q:3,ap:0/3598
# d:1.750,dm:1.730,dM:1.750,p:6.021,s:0.0,m:1504.5000,q:3,ap:0/3598
# d:1.730,dm:1.730,dM:1.750,p:11.192,s:0.0,m:1504.5000,q:3,ap:0/3598
# d:1.730,dm:1.730,dM:1.750,p:17.999,s:0.0,m:1504.5000,q:3,ap:0/3598
# d:1.730,dm:1.730,dM:1.750,p:26.049,s:0.0,m:1504.5000,q:3,ap:0/3598
#
# [...]
#
# d:1.750,dm:1.690,dM:1.820,p:1614324.750,s:49.6,m:969.1023,q:2,ap:1180/3598
# d:1.820,dm:1.690,dM:1.820,p:1614324.250,s:1.1,m:972.0096,q:2,ap:1180/3598
# MOTOR DISABLED: FILAMENT OUT OF RANGE
# #end: 20250224_232750
# Write the data to the file
with open(file_path, "w") as file:
for data in self.data_list:
file.write(data + "\n")
print(f"id{self.bench_id}:\tsaving job: {self.current_job}")
spool, vendor, material, batch, description, startstamp = self.current_job
endstamp = datetime.now().strftime("%Y%m%d_%H%M%S")
outfilename = os.path.join("data", f"{spool}_{startstamp}.fsl")
with open(outfilename, "w") as outfile:
outfile.write(F"#bench: {self.serial_number} (#{self.bench_id})\n")
outfile.write(F"#date: {startstamp}\n")
outfile.write(F"#spool: {spool}\n")
outfile.write(F"#material: {vendor} {material} {batch} {description}\n")
for position, diameter in self.data_list:
outfile.write(f"d:{diameter},p:{position}\n")
outfile.write(F"#end: {endstamp}\n")
subprocess.run(["gzip", "-9", outfilename])
def parse_data(self, data):
self.data_list.append(data)
match = re.match(r"^[#d]:(-?[\d\.]+),p:(-?[\d\.]+)$", data)
if match:
self.diameter_value = float(match.group(1))
@ -131,7 +169,7 @@ class UpdateWorker(QThread):
offset_match = re.match(r"^#h:(\d+)", data)
if offset_match:
home_offset = int(offset_match.group(1))
print(f"id{self.bench_id}:\tOffset: {home_offset:.2f}")
# print(f"id{self.bench_id}:\tOffset: {home_offset:.2f}")
self.block.btn_offset.setText(f"Offset: {home_offset:.2f}")
mode_match = re.match(r"^#o:(\d+)", data)
@ -198,6 +236,15 @@ class UpdateWorker(QThread):
self.reset_data = True
self.is_running = True
self.current_job = (
self.api_job['spool'],
self.api_job['vendor'],
self.api_job['material'],
self.api_job['batch'],
self.api_job['description'],
datetime.now().strftime("%Y%m%d_%H%M%S")
)
self.change_color_signal.emit(self.block_id, 'btn_start', "#00a000")
self.change_color_signal.emit(self.block_id, 'btn_prepare', "#5A5A5A")
@ -206,12 +253,14 @@ class UpdateWorker(QThread):
def stop_running(self):
if self.is_running:
self.send_command('R')
self.timer.start()
self.block.data_label.setText(
f"Job done, processing..."
)
# for position, diameter in self.data_list:
# print(f"{position} -> {diameter}")
self.change_color_signal.emit(self.block_id, 'btn_start', "#a00000")
self.change_color_signal.emit(self.block_id, 'btn_prepare', "#5A5A5A")
@ -341,6 +390,7 @@ class UpdateWorker(QThread):
btn_prepare = QPushButton("Prepare")
btn_prepare.clicked.connect(lambda: self.send_command('P'))
time.sleep(0.1)
btn_prepare.clicked.connect(lambda: self.set_prepare(True))
right_layout_1.addWidget(btn_prepare)
@ -498,8 +548,10 @@ class UpdateWorker(QThread):
response.raise_for_status() # Raise an exception for HTTP errors
api_job = response.json() # Parse the JSON response
if api_job is not None:
print(f"id{self.bench_id}:\tgot job {api_job['spool']} from API")
self.api_job = api_job
if self.api_job is not None:
# print(f"id{self.bench_id}:\tgot job {api_job['spool']} from API")
self.block.data_label.setText(
f"Job/Spool: {api_job['spool']}<hr>"
f"Fabricant: {api_job['vendor']}<br>"
@ -510,12 +562,11 @@ class UpdateWorker(QThread):
)
self.density = float(api_job['density'])
self.can_start = True
self.timer.stop()
else:
print(f"id{self.bench_id}:\tno job from API")
# print(f"id{self.bench_id}:\tno job from API")
self.block.data_label.setText(
f"API responded with no job"
)
self.can_start = False
except requests.RequestException as e:
print(f"Error querying API: {e}")
print(f"Error querying API: {e}")

View File

@ -1,8 +1,10 @@
#!./bin/python
import sys
from PyQt5.QtWidgets import QApplication
from BlockStackApp import BlockStackApp
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = BlockStackApp()
ex = BlockStackApp(True) # True for bordeless fullscreen, False for maximisedgit pl
sys.exit(app.exec_())