From eb397ff7b7af8c78b135866372ce187a8e0d2ed3 Mon Sep 17 00:00:00 2001 From: Manuel Weiser Date: Sun, 2 Mar 2025 10:53:37 +0100 Subject: [PATCH] Aktualisiere Temperatur- und Druckerstatusverarbeitung in BambuVirtualPrinter zur direkten Nutzung von Telemetriedaten und verbessere Fehlerbehandlung bei MQTT-Nachrichten --- .../printer/bambu_virtual_printer.py | 170 ++++++++++++++---- 1 file changed, 133 insertions(+), 37 deletions(-) diff --git a/octoprint_bambu_printer/printer/bambu_virtual_printer.py b/octoprint_bambu_printer/printer/bambu_virtual_printer.py index 12a5d47..efde15c 100644 --- a/octoprint_bambu_printer/printer/bambu_virtual_printer.py +++ b/octoprint_bambu_printer/printer/bambu_virtual_printer.py @@ -188,30 +188,38 @@ class BambuVirtualPrinter: self._update_printer_info() def _update_printer_info(self): - device_data = self.bambu_client.get_device() - print_job_state = device_data.print_job.gcode_state - temperatures = device_data.temperature - + # Verwende direkt die Telemetrie-Daten statt der BambuClient-Struktur self.lastTempAt = time.monotonic() - self._telemetry.temp[0] = temperatures.nozzle_temp - self._telemetry.targetTemp[0] = temperatures.target_nozzle_temp - self._telemetry.bedTemp = temperatures.bed_temp - self._telemetry.bedTargetTemp = temperatures.target_bed_temp - self._telemetry.chamberTemp = temperatures.chamber_temp - - self._log.debug(f"Received printer state update: {print_job_state}") - if ( - print_job_state == "IDLE" - or print_job_state == "FINISH" - or print_job_state == "FAILED" - ): - self.change_state(self._state_idle) - elif print_job_state == "RUNNING" or print_job_state == "PREPARE": - self.change_state(self._state_printing) - elif print_job_state == "PAUSE": - self.change_state(self._state_paused) - else: - self._log.warn(f"Unknown print job state: {print_job_state}") + + # Der Rest der Methode kann unverändert bleiben, da wir die Telemetrie + # direkt in _process_print_data aktualisieren + + # Gib den aktuellen Status detaillierter aus + self._log.debug(f"Current temperatures - Nozzle: {self._telemetry.temp[0]}/{self._telemetry.targetTemp[0]}, " + + f"Bed: {self._telemetry.bedTemp}/{self._telemetry.bedTargetTemp}, " + + f"Chamber: {self._telemetry.chamberTemp}") + + # Rufe trotzdem die BambuClient-Daten ab, falls verfügbar + try: + device_data = self.bambu_client.get_device() + print_job_state = device_data.print_job.gcode_state + + self._log.debug(f"BambuClient printer state: {print_job_state}") + + if ( + print_job_state == "IDLE" + or print_job_state == "FINISH" + or print_job_state == "FAILED" + ): + self.change_state(self._state_idle) + elif print_job_state == "RUNNING" or print_job_state == "PREPARE": + self.change_state(self._state_printing) + elif print_job_state == "PAUSE": + self.change_state(self._state_paused) + else: + self._log.warn(f"Unknown print job state: {print_job_state}") + except Exception as e: + self._log.error(f"Error reading BambuClient device state: {e}") def _update_hms_errors(self): bambu_printer = self.bambu_client.get_device() @@ -261,23 +269,111 @@ class BambuVirtualPrinter: try: # Decode message and update client data payload = json.loads(msg.payload.decode('utf-8')) - - # If this is a Bambu Lab printer message, process it - if 'print' in payload or 'info' in payload: - # Forward the message to pybambu for processing - if self._bambu_client: - self._bambu_client._process_message(msg.topic, payload) - - # Trigger our update handler - if 'print' in payload: - self.new_update("event_printer_data_update") - if 'info' in payload and 'hms' in payload['info']: - self.new_update("event_hms_errors") - - self._log.debug(f"MQTT message received on topic {msg.topic}") + self._log.debug(f"MQTT message received on topic {msg.topic}: {payload.keys()}") + + # Verarbeite direkt die Daten aus der MQTT-Nachricht + if 'print' in payload: + self._process_print_data(payload['print']) + # Forward the message to pybambu for its internal state + try: + if hasattr(self._bambu_client, '_process_message'): + self._bambu_client._process_message(msg.topic, payload) + else: + # Alternative Methode für pybambu + self._update_bambu_client_state(payload) + except Exception as e: + self._log.error(f"Error forwarding to pybambu: {e}") + + self.new_update("event_printer_data_update") + + if 'info' in payload: + if 'hms' in payload['info']: + # Aktualisiere HMS-Fehler direkt + try: + if hasattr(self._bambu_client.device, 'hms'): + self._bambu_client.device.hms.update_from_payload(payload['info']['hms']) + except Exception as e: + self._log.error(f"Error updating HMS data: {e}") + self.new_update("event_hms_errors") except Exception as e: self._log.error(f"Error processing MQTT message: {e}") + def _process_print_data(self, print_data): + """Verarbeitet direkt die Druckerdaten aus der MQTT-Nachricht""" + try: + # Aktualisiere Temperaturdaten direkt + if 'temperature' in print_data: + temp_data = print_data['temperature'] + + # Extruder Temperatur + if 'nozzle_temp' in temp_data: + self._telemetry.temp[0] = float(temp_data['nozzle_temp']) + if 'target_nozzle_temp' in temp_data: + self._telemetry.targetTemp[0] = float(temp_data['target_nozzle_temp']) + + # Bett Temperatur + if 'bed_temp' in temp_data: + self._telemetry.bedTemp = float(temp_data['bed_temp']) + if 'target_bed_temp' in temp_data: + self._telemetry.bedTargetTemp = float(temp_data['target_bed_temp']) + + # Kammer Temperatur + if 'chamber_temp' in temp_data: + self._telemetry.chamberTemp = float(temp_data['chamber_temp']) + + self._log.debug(f"Updated temperatures - Nozzle: {self._telemetry.temp[0]}/{self._telemetry.targetTemp[0]}, " + + f"Bed: {self._telemetry.bedTemp}/{self._telemetry.bedTargetTemp}, " + + f"Chamber: {self._telemetry.chamberTemp}") + + # Aktualisiere Druckerstatus + if 'gcode_state' in print_data: + print_job_state = print_data['gcode_state'] + self._log.debug(f"Received printer state update: {print_job_state}") + + if print_job_state in ["IDLE", "FINISH", "FAILED"]: + self.change_state(self._state_idle) + elif print_job_state in ["RUNNING", "PREPARE"]: + self.change_state(self._state_printing) + elif print_job_state == "PAUSE": + self.change_state(self._state_paused) + else: + self._log.warn(f"Unknown print job state: {print_job_state}") + + # Aktualisiere auch die pybambu-Datenstruktur + if hasattr(self._bambu_client, 'device') and hasattr(self._bambu_client.device, 'print_job'): + self._bambu_client.device.print_job.gcode_state = print_job_state + except Exception as e: + self._log.error(f"Error processing print data: {e}") + + def _update_bambu_client_state(self, payload): + """Aktualisiert die internen Zustände des BambuClient""" + try: + if not hasattr(self._bambu_client, 'device'): + self._log.debug("BambuClient has no device attribute, initializing") + return + + if 'print' in payload: + print_data = payload['print'] + + # Temperatur aktualisieren + if 'temperature' in print_data and hasattr(self._bambu_client.device, 'temperature'): + temp_obj = self._bambu_client.device.temperature + temp_data = print_data['temperature'] + + # Direkte Zuweisung der Temperaturen + if 'nozzle_temp' in temp_data: + temp_obj.nozzle_temp = float(temp_data['nozzle_temp']) + if 'target_nozzle_temp' in temp_data: + temp_obj.target_nozzle_temp = float(temp_data['target_nozzle_temp']) + if 'bed_temp' in temp_data: + temp_obj.bed_temp = float(temp_data['bed_temp']) + if 'target_bed_temp' in temp_data: + temp_obj.target_bed_temp = float(temp_data['target_bed_temp']) + if 'chamber_temp' in temp_data: + temp_obj.chamber_temp = float(temp_data['chamber_temp']) + except Exception as e: + self._log.error(f"Error updating BambuClient state: {e}") + def _create_client_connection_async(self): self._create_client_connection() if self._bambu_client is None: