From 72856ace3cf4ff61a0e2311a8413ad26f5d2e394 Mon Sep 17 00:00:00 2001 From: Jonathan Roth Date: Mon, 14 Apr 2025 12:27:23 +0200 Subject: [PATCH] dev --- BlockStackApp.py | 22 ++++++++---- UpdateWorker.py | 93 +++++++++++++++++++++++++++++++++++++----------- fdr1gui.py | 4 ++- 3 files changed, 91 insertions(+), 28 deletions(-) diff --git a/BlockStackApp.py b/BlockStackApp.py index 5915aba..8b79ff1 100644 --- a/BlockStackApp.py +++ b/BlockStackApp.py @@ -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 diff --git a/UpdateWorker.py b/UpdateWorker.py index 5fad03a..6aefcdb 100644 --- a/UpdateWorker.py +++ b/UpdateWorker.py @@ -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']}
" f"Fabricant: {api_job['vendor']}
" @@ -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}") \ No newline at end of file + print(f"Error querying API: {e}") diff --git a/fdr1gui.py b/fdr1gui.py index d1b5d8c..685add8 100644 --- a/fdr1gui.py +++ b/fdr1gui.py @@ -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_()) \ No newline at end of file