update
Browse files
app.py
CHANGED
|
@@ -38,8 +38,8 @@ client = None
|
|
| 38 |
latest_data = {
|
| 39 |
"bed_temperature": "N/A",
|
| 40 |
"nozzle_temperature": "N/A",
|
| 41 |
-
"status": "
|
| 42 |
-
"update_time": "
|
| 43 |
}
|
| 44 |
|
| 45 |
# Initialize analysis components
|
|
@@ -97,56 +97,20 @@ def create_3mf_package(gcode_content: str, gcode_filename: str = "Metadata/plate
|
|
| 97 |
zip_buffer.seek(0)
|
| 98 |
return zip_buffer
|
| 99 |
|
| 100 |
-
def create_client(host, port, username, password
|
| 101 |
-
"""Create MQTT client with retry mechanism"""
|
| 102 |
global client
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
client.on_message = on_message
|
| 111 |
-
client.on_disconnect = on_disconnect
|
| 112 |
-
|
| 113 |
-
print(f"Attempting to connect to MQTT broker (attempt {attempt + 1}/{max_retries})")
|
| 114 |
-
client.connect(host, port, keepalive=60)
|
| 115 |
-
client.loop_start()
|
| 116 |
-
return True
|
| 117 |
-
|
| 118 |
-
except Exception as e:
|
| 119 |
-
print(f"Connection attempt {attempt + 1} failed: {e}")
|
| 120 |
-
if client:
|
| 121 |
-
client.loop_stop()
|
| 122 |
-
client = None
|
| 123 |
-
if attempt < max_retries - 1:
|
| 124 |
-
time.sleep(5)
|
| 125 |
-
|
| 126 |
-
print("Failed to connect to MQTT broker after all attempts")
|
| 127 |
-
return False
|
| 128 |
|
| 129 |
def on_connect(client, userdata, flags, rc):
|
| 130 |
-
"
|
| 131 |
-
if rc == 0:
|
| 132 |
-
print("Successfully connected to MQTT broker")
|
| 133 |
-
response_topic = f"bambu_a1_mini/response/{PRINTER_SERIAL}"
|
| 134 |
-
request_topic = f"bambu_a1_mini/request/{PRINTER_SERIAL}"
|
| 135 |
-
client.subscribe(response_topic)
|
| 136 |
-
print(f"Subscribed to {response_topic}")
|
| 137 |
-
|
| 138 |
-
# Send initial request
|
| 139 |
-
client.publish(request_topic, json.dumps("HI"))
|
| 140 |
-
|
| 141 |
-
# Update status
|
| 142 |
-
global latest_data
|
| 143 |
-
latest_data["status"] = "Connected"
|
| 144 |
-
latest_data["update_time"] = time.strftime("%Y-%m-%d %H:%M:%S")
|
| 145 |
-
else:
|
| 146 |
-
print(f"Failed to connect to MQTT broker with code: {rc}")
|
| 147 |
|
| 148 |
def on_message(client, userdata, message):
|
| 149 |
-
"""Handle incoming MQTT messages"""
|
| 150 |
global latest_data
|
| 151 |
print("Received message")
|
| 152 |
try:
|
|
@@ -154,146 +118,45 @@ def on_message(client, userdata, message):
|
|
| 154 |
latest_data["bed_temperature"] = data.get("bed_temperature", "N/A")
|
| 155 |
latest_data["nozzle_temperature"] = data.get("nozzle_temperature", "N/A")
|
| 156 |
latest_data["status"] = data.get("status", "N/A")
|
| 157 |
-
latest_data["update_time"] = time.strftime("%Y-%m-%d %H:%M:%S")
|
| 158 |
except Exception as e:
|
| 159 |
print(f"Error parsing MQTT message: {e}")
|
| 160 |
|
| 161 |
-
def
|
| 162 |
-
"""
|
| 163 |
-
|
| 164 |
-
global latest_data
|
| 165 |
-
latest_data["status"] = "Disconnected"
|
| 166 |
-
latest_data["update_time"] = time.strftime("%Y-%m-%d %H:%M:%S")
|
| 167 |
-
|
| 168 |
-
if rc != 0:
|
| 169 |
-
print("Unexpected disconnection. Attempting to reconnect...")
|
| 170 |
-
create_client(HOST, PORT, USERNAME, PASSWORD)
|
| 171 |
-
|
| 172 |
-
def send_print_command(params):
|
| 173 |
-
"""Send print parameters to Pi 4B"""
|
| 174 |
-
command = create_print_command(params)
|
| 175 |
-
mqtt_client.publish(TOPICS['printer']['command'], json.dumps(command))
|
| 176 |
-
logger.info(f"Print command sent for square {params.get('square_id')}")
|
| 177 |
-
return "Print command sent successfully"
|
| 178 |
-
|
| 179 |
-
def send_camera_command(square_id: str):
|
| 180 |
-
"""Send capture command to Pi Zero"""
|
| 181 |
-
command = create_capture_command(square_id)
|
| 182 |
-
mqtt_client.publish(TOPICS['camera']['command'], json.dumps(command))
|
| 183 |
-
logger.info(f"Camera command sent for square {square_id}")
|
| 184 |
-
return "Camera command sent successfully"
|
| 185 |
-
|
| 186 |
-
def send_print_parameters(nozzle_temp, bed_temp, print_speed, fan_speed):
|
| 187 |
-
"""Send new print parameters to printer"""
|
| 188 |
-
try:
|
| 189 |
-
params = {
|
| 190 |
-
'nozzle_temp': nozzle_temp,
|
| 191 |
-
'bed_temp': bed_temp,
|
| 192 |
-
'print_speed': print_speed,
|
| 193 |
-
'fan_speed': fan_speed
|
| 194 |
-
}
|
| 195 |
-
|
| 196 |
-
request_topic = f"bambu_a1_mini/request/{PRINTER_SERIAL}"
|
| 197 |
-
if client:
|
| 198 |
-
client.publish(request_topic, json.dumps({
|
| 199 |
-
'command': 'set_parameters',
|
| 200 |
-
'parameters': params
|
| 201 |
-
}))
|
| 202 |
-
return "Parameters sent successfully"
|
| 203 |
-
return "MQTT not connected"
|
| 204 |
-
except Exception as e:
|
| 205 |
-
return f"Error sending parameters: {e}"
|
| 206 |
-
|
| 207 |
-
# Initialize MQTT client
|
| 208 |
-
try:
|
| 209 |
-
mqtt_connected = create_client(HOST, PORT, USERNAME, PASSWORD)
|
| 210 |
-
if not mqtt_connected:
|
| 211 |
-
print("Warning: Starting without MQTT connection")
|
| 212 |
-
except Exception as e:
|
| 213 |
-
print(f"Warning: Failed to initialize MQTT: {e}")
|
| 214 |
-
|
| 215 |
-
def update_status():
|
| 216 |
-
"""Update printer status display"""
|
| 217 |
if client is None:
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
try:
|
| 221 |
-
request_topic = f"bambu_a1_mini/request/{PRINTER_SERIAL}"
|
| 222 |
-
client.publish(request_topic, json.dumps("HI"))
|
| 223 |
-
|
| 224 |
-
return (
|
| 225 |
-
latest_data["nozzle_temperature"],
|
| 226 |
-
latest_data["bed_temperature"],
|
| 227 |
-
latest_data["status"],
|
| 228 |
-
latest_data["update_time"]
|
| 229 |
-
)
|
| 230 |
-
except Exception as e:
|
| 231 |
-
print(f"Status update error: {e}")
|
| 232 |
-
return "N/A", "N/A", "Error", str(e)
|
| 233 |
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
return None, 0, 0, 0, 0, 0, 0, 0, 0
|
| 238 |
-
|
| 239 |
-
# Package current parameters
|
| 240 |
-
current_params = {
|
| 241 |
-
'nozzle_temp': float(nozzle_temp),
|
| 242 |
-
'bed_temp': float(bed_temp),
|
| 243 |
-
'print_speed': float(print_speed),
|
| 244 |
-
'fan_speed': float(fan_speed)
|
| 245 |
-
}
|
| 246 |
|
| 247 |
-
|
| 248 |
-
|
| 249 |
|
| 250 |
-
#
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
# Calculate quality metrics
|
| 254 |
-
metrics = detector.calculate_quality_metrics(image)
|
| 255 |
|
| 256 |
return (
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
float(metrics['uniformity_score']),
|
| 262 |
-
float(analysis_results['quality_score']),
|
| 263 |
-
float(results['objectives']['speed']),
|
| 264 |
-
float(results['objectives']['material']),
|
| 265 |
-
float(results['objectives']['total'])
|
| 266 |
)
|
| 267 |
|
| 268 |
# Gradio interface
|
| 269 |
with gr.Blocks(title="Bambu A1 Mini Print Analysis") as demo:
|
| 270 |
gr.Markdown("# Bambu A1 Mini Print Quality Analysis")
|
| 271 |
|
| 272 |
-
# Current printer parameters display
|
| 273 |
with gr.Row():
|
| 274 |
-
current_nozzle_temp = gr.Textbox(
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
current_bed_temp = gr.Textbox(
|
| 280 |
-
label="Current Bed Temperature",
|
| 281 |
-
value="N/A",
|
| 282 |
-
interactive=False
|
| 283 |
-
)
|
| 284 |
-
current_status = gr.Textbox(
|
| 285 |
-
label="Printer Status",
|
| 286 |
-
value="N/A",
|
| 287 |
-
interactive=False
|
| 288 |
-
)
|
| 289 |
-
last_update = gr.Textbox(
|
| 290 |
-
label="Last Update",
|
| 291 |
-
value="N/A",
|
| 292 |
-
interactive=False
|
| 293 |
-
)
|
| 294 |
-
|
| 295 |
refresh_btn = gr.Button("Refresh Status")
|
| 296 |
-
|
| 297 |
with gr.Row():
|
| 298 |
# show S3 image
|
| 299 |
s3_image = gr.Image(
|
|
@@ -305,37 +168,21 @@ with gr.Blocks(title="Bambu A1 Mini Print Analysis") as demo:
|
|
| 305 |
label="Current Print Image",
|
| 306 |
type="numpy"
|
| 307 |
)
|
| 308 |
-
|
| 309 |
with gr.Row():
|
| 310 |
with gr.Column():
|
| 311 |
# Print parameter inputs
|
| 312 |
-
nozzle_temp = gr.Slider(
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
)
|
| 317 |
-
bed_temp = gr.Slider(
|
| 318 |
-
minimum=40, maximum=100, step=1,
|
| 319 |
-
value=60,
|
| 320 |
-
label="Bed Temperature (°C)"
|
| 321 |
-
)
|
| 322 |
-
print_speed = gr.Slider(
|
| 323 |
-
minimum=20, maximum=150, step=1,
|
| 324 |
-
value=60,
|
| 325 |
-
label="Print Speed (mm/s)"
|
| 326 |
-
)
|
| 327 |
-
fan_speed = gr.Slider(
|
| 328 |
-
minimum=0, maximum=100, step=1,
|
| 329 |
-
value=100,
|
| 330 |
-
label="Fan Speed (%)"
|
| 331 |
-
)
|
| 332 |
|
| 333 |
# Buttons
|
| 334 |
with gr.Row():
|
| 335 |
capture_btn = gr.Button("Capture Image")
|
| 336 |
analyze_btn = gr.Button("Analyze Print")
|
| 337 |
-
send_params_btn = gr.Button("Send Print Parameters")
|
| 338 |
-
|
| 339 |
with gr.Column():
|
| 340 |
# Results visualization
|
| 341 |
result_image = gr.Image(label="Analysis Result")
|
|
@@ -398,38 +245,17 @@ with gr.Blocks(title="Bambu A1 Mini Print Analysis") as demo:
|
|
| 398 |
)
|
| 399 |
|
| 400 |
# connect refresh button
|
| 401 |
-
|
| 402 |
-
"""Update printer status display"""
|
| 403 |
-
return (
|
| 404 |
-
latest_data["nozzle_temperature"],
|
| 405 |
-
latest_data["bed_temperature"],
|
| 406 |
-
latest_data["status"],
|
| 407 |
-
latest_data["update_time"]
|
| 408 |
-
)
|
| 409 |
-
|
| 410 |
-
refresh_btn.click(
|
| 411 |
-
fn=update_status,
|
| 412 |
-
outputs=[
|
| 413 |
-
current_nozzle_temp,
|
| 414 |
-
current_bed_temp,
|
| 415 |
-
current_status,
|
| 416 |
-
last_update
|
| 417 |
-
]
|
| 418 |
-
)
|
| 419 |
|
| 420 |
# Auto refresh
|
| 421 |
def auto_refresh():
|
| 422 |
while True:
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
last_update.value = values[3]
|
| 430 |
-
except Exception as e:
|
| 431 |
-
print(f"Auto refresh error: {e}")
|
| 432 |
-
continue
|
| 433 |
|
| 434 |
threading.Thread(target=auto_refresh, daemon=True).start()
|
| 435 |
|
|
@@ -440,27 +266,61 @@ with gr.Blocks(title="Bambu A1 Mini Print Analysis") as demo:
|
|
| 440 |
outputs=[current_status]
|
| 441 |
)
|
| 442 |
|
| 443 |
-
def
|
| 444 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
try:
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
|
| 453 |
-
# 3. Send capture command to Pi Zero
|
| 454 |
-
camera_command = create_capture_command(params['square_id'])
|
| 455 |
-
mqtt_client.publish(TOPICS['camera']['command'], json.dumps(camera_command))
|
| 456 |
-
|
| 457 |
-
# 4. Wait for image URL
|
| 458 |
-
# (handle by on_message callback)
|
| 459 |
|
| 460 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 461 |
except Exception as e:
|
| 462 |
-
return f"Error: {
|
| 463 |
|
| 464 |
# Launch the app
|
| 465 |
if __name__ == "__main__":
|
| 466 |
-
demo.launch(
|
|
|
|
| 38 |
latest_data = {
|
| 39 |
"bed_temperature": "N/A",
|
| 40 |
"nozzle_temperature": "N/A",
|
| 41 |
+
"status": "N/A",
|
| 42 |
+
"update_time": "Waiting for data..."
|
| 43 |
}
|
| 44 |
|
| 45 |
# Initialize analysis components
|
|
|
|
| 97 |
zip_buffer.seek(0)
|
| 98 |
return zip_buffer
|
| 99 |
|
| 100 |
+
def create_client(host, port, username, password):
|
|
|
|
| 101 |
global client
|
| 102 |
+
client = mqtt.Client()
|
| 103 |
+
client.username_pw_set(username, password)
|
| 104 |
+
client.tls_set(tls_version=mqtt.ssl.PROTOCOL_TLS)
|
| 105 |
+
client.on_connect = on_connect
|
| 106 |
+
client.on_message = on_message
|
| 107 |
+
client.connect(host, port)
|
| 108 |
+
client.loop_start()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
def on_connect(client, userdata, flags, rc):
|
| 111 |
+
print(f"Connected with result code {rc}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
def on_message(client, userdata, message):
|
|
|
|
| 114 |
global latest_data
|
| 115 |
print("Received message")
|
| 116 |
try:
|
|
|
|
| 118 |
latest_data["bed_temperature"] = data.get("bed_temperature", "N/A")
|
| 119 |
latest_data["nozzle_temperature"] = data.get("nozzle_temperature", "N/A")
|
| 120 |
latest_data["status"] = data.get("status", "N/A")
|
| 121 |
+
latest_data["update_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
| 122 |
except Exception as e:
|
| 123 |
print(f"Error parsing MQTT message: {e}")
|
| 124 |
|
| 125 |
+
def get_data():
|
| 126 |
+
"""Request data from the MQTT broker."""
|
| 127 |
+
global client
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
if client is None:
|
| 129 |
+
create_client(HOST, PORT, USERNAME, PASSWORD)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
+
serial = "0309CA471800852"
|
| 132 |
+
request_topic = f"bambu_a1_mini/request/{serial}"
|
| 133 |
+
response_topic = f"bambu_a1_mini/response/{serial}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
+
print(f"Subscribing to {response_topic}")
|
| 136 |
+
client.subscribe(response_topic)
|
| 137 |
|
| 138 |
+
# Send a request to get data
|
| 139 |
+
client.publish(request_topic, json.dumps("HI"))
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
return (
|
| 142 |
+
latest_data["status"],
|
| 143 |
+
latest_data["bed_temperature"],
|
| 144 |
+
latest_data["nozzle_temperature"],
|
| 145 |
+
latest_data["update_time"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
)
|
| 147 |
|
| 148 |
# Gradio interface
|
| 149 |
with gr.Blocks(title="Bambu A1 Mini Print Analysis") as demo:
|
| 150 |
gr.Markdown("# Bambu A1 Mini Print Quality Analysis")
|
| 151 |
|
|
|
|
| 152 |
with gr.Row():
|
| 153 |
+
current_nozzle_temp = gr.Textbox(label="Current Nozzle Temperature", value="N/A", interactive=False)
|
| 154 |
+
current_bed_temp = gr.Textbox(label="Current Bed Temperature", value="N/A", interactive=False)
|
| 155 |
+
current_status = gr.Textbox(label="Printer Status", value="N/A", interactive=False)
|
| 156 |
+
last_update = gr.Textbox(label="Last Update", value="N/A", interactive=False)
|
| 157 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
refresh_btn = gr.Button("Refresh Status")
|
| 159 |
+
|
| 160 |
with gr.Row():
|
| 161 |
# show S3 image
|
| 162 |
s3_image = gr.Image(
|
|
|
|
| 168 |
label="Current Print Image",
|
| 169 |
type="numpy"
|
| 170 |
)
|
| 171 |
+
|
| 172 |
with gr.Row():
|
| 173 |
with gr.Column():
|
| 174 |
# Print parameter inputs
|
| 175 |
+
nozzle_temp = gr.Slider(minimum=180, maximum=250, step=1, value=200, label="Nozzle Temperature (°C)")
|
| 176 |
+
bed_temp = gr.Slider(minimum=40, maximum=100, step=1, value=60, label="Bed Temperature (°C)")
|
| 177 |
+
print_speed = gr.Slider(minimum=20, maximum=150, step=1, value=60, label="Print Speed (mm/s)")
|
| 178 |
+
fan_speed = gr.Slider(minimum=0, maximum=100, step=1, value=100, label="Fan Speed (%)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
|
| 180 |
# Buttons
|
| 181 |
with gr.Row():
|
| 182 |
capture_btn = gr.Button("Capture Image")
|
| 183 |
analyze_btn = gr.Button("Analyze Print")
|
| 184 |
+
send_params_btn = gr.Button("Send Print Parameters")
|
| 185 |
+
|
| 186 |
with gr.Column():
|
| 187 |
# Results visualization
|
| 188 |
result_image = gr.Image(label="Analysis Result")
|
|
|
|
| 245 |
)
|
| 246 |
|
| 247 |
# connect refresh button
|
| 248 |
+
refresh_btn.click(fn=get_data, outputs=[current_status, current_bed_temp, current_nozzle_temp, last_update])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
|
| 250 |
# Auto refresh
|
| 251 |
def auto_refresh():
|
| 252 |
while True:
|
| 253 |
+
time.sleep(5)
|
| 254 |
+
status, bed_temp, nozzle_temp, update_time = get_data()
|
| 255 |
+
current_status.value = status
|
| 256 |
+
current_bed_temp.value = bed_temp
|
| 257 |
+
current_nozzle_temp.value = nozzle_temp
|
| 258 |
+
last_update.value = update_time
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
|
| 260 |
threading.Thread(target=auto_refresh, daemon=True).start()
|
| 261 |
|
|
|
|
| 266 |
outputs=[current_status]
|
| 267 |
)
|
| 268 |
|
| 269 |
+
def analyze_print(image, nozzle_temp, bed_temp, print_speed, fan_speed):
|
| 270 |
+
"""Analyze print quality and return evaluation results"""
|
| 271 |
+
if image is None:
|
| 272 |
+
return None, 0, 0, 0, 0, 0, 0, 0, 0
|
| 273 |
+
|
| 274 |
+
# Package current parameters
|
| 275 |
+
current_params = {
|
| 276 |
+
'nozzle_temp': float(nozzle_temp),
|
| 277 |
+
'bed_temp': float(bed_temp),
|
| 278 |
+
'print_speed': float(print_speed),
|
| 279 |
+
'fan_speed': float(fan_speed)
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
# Analyze print quality
|
| 283 |
+
analysis_results = detector.analyze_print(image)
|
| 284 |
+
|
| 285 |
+
# Get optimization results
|
| 286 |
+
results = optimizer.evaluate_objectives(image, current_params)
|
| 287 |
+
|
| 288 |
+
# Calculate quality metrics
|
| 289 |
+
metrics = detector.calculate_quality_metrics(image)
|
| 290 |
+
|
| 291 |
+
return (
|
| 292 |
+
analysis_results['binary_mask'], # Visualization
|
| 293 |
+
float(metrics['missing_rate']),
|
| 294 |
+
float(metrics['excess_rate']),
|
| 295 |
+
float(metrics['stringing_rate']),
|
| 296 |
+
float(metrics['uniformity_score']),
|
| 297 |
+
float(analysis_results['quality_score']),
|
| 298 |
+
float(results['objectives']['speed']),
|
| 299 |
+
float(results['objectives']['material']),
|
| 300 |
+
float(results['objectives']['total'])
|
| 301 |
+
)
|
| 302 |
+
|
| 303 |
+
def send_print_parameters(nozzle_temp, bed_temp, print_speed, fan_speed):
|
| 304 |
+
"""Send new print parameters to printer"""
|
| 305 |
try:
|
| 306 |
+
params = {
|
| 307 |
+
'nozzle_temp': nozzle_temp,
|
| 308 |
+
'bed_temp': bed_temp,
|
| 309 |
+
'print_speed': print_speed,
|
| 310 |
+
'fan_speed': fan_speed
|
| 311 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 312 |
|
| 313 |
+
request_topic = f"bambu_a1_mini/request/{PRINTER_SERIAL}"
|
| 314 |
+
if client:
|
| 315 |
+
client.publish(request_topic, json.dumps({
|
| 316 |
+
'command': 'set_parameters',
|
| 317 |
+
'parameters': params
|
| 318 |
+
}))
|
| 319 |
+
return "Parameters sent successfully"
|
| 320 |
+
return "MQTT not connected"
|
| 321 |
except Exception as e:
|
| 322 |
+
return f"Error sending parameters: {e}"
|
| 323 |
|
| 324 |
# Launch the app
|
| 325 |
if __name__ == "__main__":
|
| 326 |
+
demo.launch()
|