SissiFeng commited on
Commit
26dfcef
·
verified ·
1 Parent(s): 152e88c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -41
app.py CHANGED
@@ -47,6 +47,8 @@ latest_data = {
47
  "status": "N/A",
48
  "update_time": "Waiting for data...",
49
  "image_url": "N/A",
 
 
50
  }
51
 
52
  bambu_client = None
@@ -94,14 +96,54 @@ def bambu_on_message(client, userdata, message):
94
  logger.error(f"Error parsing MQTT message: {e}")
95
 
96
 
97
- def rpi_on_message(client, userdata, message):
98
  global latest_data
99
- logger.info("Received message")
100
  try:
101
- data = json.loads(message.payload)
102
- latest_data["image_url"] = data.get("image_url", "N/A")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  except Exception as e:
104
- logger.error(f"Error parsing MQTT message: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
 
107
  def get_data(serial=DEFAULT_SERIAL):
@@ -135,12 +177,15 @@ def get_data(serial=DEFAULT_SERIAL):
135
 
136
 
137
  def send_print_parameters(nozzle_temp, bed_temp, print_speed, fan_speed):
138
- global bambu_client
139
 
140
  serial = DEFAULT_SERIAL
 
141
  logger.info(
142
- f"Sending parameters to {serial}: nozzle={nozzle_temp}, bed={bed_temp}, speed={print_speed}, fan={fan_speed}"
 
143
  )
 
144
  try:
145
  params = {
146
  "nozzle_temp": nozzle_temp,
@@ -151,13 +196,18 @@ def send_print_parameters(nozzle_temp, bed_temp, print_speed, fan_speed):
151
 
152
  request_topic = f"bambu_a1_mini/request/{serial}"
153
 
154
- if bambu_client:
155
- bambu_client.publish(
156
  request_topic,
157
- json.dumps({"command": "set_parameters", "parameters": params}),
158
  )
159
- logger.info("Parameters sent successfully")
160
- return "Parameters sent successfully"
 
 
 
 
 
161
  else:
162
  logger.warning("MQTT not connected, parameters not sent")
163
  return "MQTT not connected, parameters not sent"
@@ -165,6 +215,12 @@ def send_print_parameters(nozzle_temp, bed_temp, print_speed, fan_speed):
165
  logger.error(f"Error sending parameters: {e}")
166
  return f"Error sending parameters: {e}"
167
 
 
 
 
 
 
 
168
 
169
  def get_image_base64(image):
170
  if image is None:
@@ -185,35 +241,21 @@ def get_image_base64(image):
185
  return None
186
 
187
 
188
- def get_test_image(image_name=None):
189
- test_dir = os.path.join(os.path.dirname(__file__), "test_images")
190
-
191
- if not os.path.exists(test_dir):
192
- logger.error(f"Test images directory not found: {test_dir}")
193
- return None
194
-
195
- image_files = [
196
- f
197
- for f in os.listdir(test_dir)
198
- if f.lower().endswith((".png", ".jpg", ".jpeg", ".bmp"))
199
- ]
200
-
201
- if not image_files:
202
- logger.error("No test images found")
203
- return None
204
-
205
- if image_name and image_name in image_files:
206
- image_path = os.path.join(test_dir, image_name)
207
- else:
208
- image_path = os.path.join(test_dir, random.choice(image_files))
209
-
210
- logger.info(f"Using test image: {image_path}")
211
-
212
  try:
213
- return Image.open(image_path)
 
 
 
 
 
 
 
 
 
214
  except Exception as e:
215
- logger.error(f"Failed to open test image: {e}")
216
- return None
217
 
218
 
219
  def capture_image(url=None, use_test_image=False, test_image_name=None):
@@ -268,6 +310,17 @@ def capture_image(url=None, use_test_image=False, test_image_name=None):
268
  else:
269
  raise Exception("url is 'N/A'")
270
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  def health_check():
273
  status = {
@@ -314,7 +367,7 @@ with demo:
314
  <div style="position: relative; width: 100%; padding-top: 56.25%;">
315
  <iframe
316
  style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
317
- src="https://www.youtube.com/embed/XoYGeFxKpH0"
318
  title="Bambu A1mini Livestream"
319
  frameborder="0"
320
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
@@ -560,6 +613,27 @@ with demo:
560
  api_name="send_print_parameters",
561
  )
562
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  if __name__ == "__main__":
564
  logger.info("Starting Bambu A1 Mini Print Control application")
565
 
@@ -577,4 +651,4 @@ if __name__ == "__main__":
577
 
578
  demo.queue().launch(
579
  show_error=True, share=False, server_name="0.0.0.0", server_port=7860
580
- )
 
47
  "status": "N/A",
48
  "update_time": "Waiting for data...",
49
  "image_url": "N/A",
50
+ "progress": 0,
51
+ "message": "",
52
  }
53
 
54
  bambu_client = None
 
96
  logger.error(f"Error parsing MQTT message: {e}")
97
 
98
 
99
+ def rpi_on_message(client, userdata, msg):
100
  global latest_data
101
+
102
  try:
103
+ payload = msg.payload.decode("utf-8")
104
+ logger.info(f"Received message from RPI: {payload}")
105
+
106
+ data = json.loads(payload)
107
+ status = data.get("status", "Unknown")
108
+
109
+ latest_data["status"] = status
110
+ latest_data["update_time"] = data.get("update_time", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
111
+
112
+ if "nozzle_temperature" in data:
113
+ latest_data["nozzle_temperature"] = data["nozzle_temperature"]
114
+
115
+ if "bed_temperature" in data:
116
+ latest_data["bed_temperature"] = data["bed_temperature"]
117
+
118
+ if "error" in data:
119
+ logger.error(f"Error from RPI: {data['error']}")
120
+
121
+ if status == "Ready":
122
+ latest_data["progress"] = 0
123
+ latest_data["message"] = "Printer ready"
124
+ elif status == "Processing":
125
+ latest_data["progress"] = 25
126
+ latest_data["message"] = "Processing G-code..."
127
+
128
  except Exception as e:
129
+ logger.error(f"Error processing message from RPI: {e}")
130
+
131
+ try:
132
+ result = json.loads(payload)
133
+
134
+ if "status" in result:
135
+ status = result["status"]
136
+ latest_data["status"] = status
137
+
138
+ if "command" in result and result["command"] == "capture_image" and result.get("auto_triggered", False):
139
+ logger.info("receive capture command")
140
+ threading.Thread(target=handle_auto_capture, args=(result,), daemon=True).start()
141
+
142
+ except json.JSONDecodeError:
143
+ logger.error(f"Invalid JSON in message: {payload}")
144
+
145
+ except Exception as e:
146
+ logger.error(f"Error processing RPI message: {e}")
147
 
148
 
149
  def get_data(serial=DEFAULT_SERIAL):
 
177
 
178
 
179
  def send_print_parameters(nozzle_temp, bed_temp, print_speed, fan_speed):
180
+ global rpi_client
181
 
182
  serial = DEFAULT_SERIAL
183
+
184
  logger.info(
185
+ f"Sending parameters to RPi for G-code generation: nozzle={nozzle_temp}, bed={bed_temp}, "
186
+ f"speed={print_speed}, fan={fan_speed}"
187
  )
188
+
189
  try:
190
  params = {
191
  "nozzle_temp": nozzle_temp,
 
196
 
197
  request_topic = f"bambu_a1_mini/request/{serial}"
198
 
199
+ if rpi_client:
200
+ rpi_client.publish(
201
  request_topic,
202
+ json.dumps({"command": "generate_gcode", "parameters": params}),
203
  )
204
+ logger.info("Parameters sent successfully to RPi for G-code generation")
205
+
206
+ global latest_data
207
+ latest_data["status"] = "Sent"
208
+ latest_data["update_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
209
+
210
+ return "Parameters sent successfully to RPi. Status: Sent"
211
  else:
212
  logger.warning("MQTT not connected, parameters not sent")
213
  return "MQTT not connected, parameters not sent"
 
215
  logger.error(f"Error sending parameters: {e}")
216
  return f"Error sending parameters: {e}"
217
 
218
+
219
+ latest_data["status"] = "Sending"
220
+ latest_data["progress"] = 10
221
+ latest_data["message"] = "Sending parameters to printer..."
222
+
223
+
224
 
225
  def get_image_base64(image):
226
  if image is None:
 
241
  return None
242
 
243
 
244
+ def handle_auto_capture(message):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  try:
246
+ logger.info(f"receive capture command: {message}")
247
+
248
+ print_job = message.get("print_job", "unknown_job")
249
+ timestamp = message.get("timestamp", time.strftime("%Y-%m-%d %H:%M:%S"))
250
+
251
+ latest_data["auto_capture_requested"] = True
252
+ latest_data["last_capture_job"] = print_job
253
+ latest_data["last_capture_time"] = timestamp
254
+
255
+ return capture_image()
256
  except Exception as e:
257
+ logger.error(f"error: {e}")
258
+ return None, f"capture failed: {str(e)}"
259
 
260
 
261
  def capture_image(url=None, use_test_image=False, test_image_name=None):
 
310
  else:
311
  raise Exception("url is 'N/A'")
312
 
313
+ def update_print_status():
314
+ global latest_data
315
+ return (
316
+ latest_data["status"],
317
+ latest_data["nozzle_temperature"],
318
+ latest_data["bed_temperature"],
319
+ latest_data["update_time"],
320
+ latest_data.get("progress", 0),
321
+ latest_data.get("message", ""),
322
+ )
323
+
324
 
325
  def health_check():
326
  status = {
 
367
  <div style="position: relative; width: 100%; padding-top: 56.25%;">
368
  <iframe
369
  style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
370
+ src="https://www.youtube.com/embed/x8Iii1cKWB8"
371
  title="Bambu A1mini Livestream"
372
  frameborder="0"
373
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
 
613
  api_name="send_print_parameters",
614
  )
615
 
616
+ get_status_api = demo.load(
617
+ fn=update_print_status,
618
+ inputs=[],
619
+ outputs=[
620
+ gr.Textbox(label="Status"),
621
+ gr.Textbox(label="Nozzle Temperature"),
622
+ gr.Textbox(label="Bed Temperature"),
623
+ gr.Textbox(label="Update Time"),
624
+ gr.Number(label="Progress"),
625
+ gr.Textbox(label="Message"),
626
+ ],
627
+ api_name="get_status",
628
+ )
629
+
630
+ health_check_api = demo.load(
631
+ fn=health_check,
632
+ inputs=[],
633
+ outputs=gr.JSON(),
634
+ api_name="health_check",
635
+ )
636
+
637
  if __name__ == "__main__":
638
  logger.info("Starting Bambu A1 Mini Print Control application")
639
 
 
651
 
652
  demo.queue().launch(
653
  show_error=True, share=False, server_name="0.0.0.0", server_port=7860
654
+ )