Implement idle state. Fix serial io
This commit is contained in:
		@@ -25,17 +25,19 @@ class APrinterState:
 | 
			
		||||
    def handle_gcode(self, gcode):
 | 
			
		||||
        self._log.debug(f"{self.__class__.__name__} gcode execution disabled")
 | 
			
		||||
 | 
			
		||||
    def connect(self):
 | 
			
		||||
        self._log_skip_state_transition("connect")
 | 
			
		||||
    def start_new_print(self):
 | 
			
		||||
        self._log_skip_state_transition("start_new_print")
 | 
			
		||||
 | 
			
		||||
    def pause(self):
 | 
			
		||||
        self._log_skip_state_transition("pause")
 | 
			
		||||
    def pause_print(self):
 | 
			
		||||
        self._log_skip_state_transition("pause_print")
 | 
			
		||||
 | 
			
		||||
    def cancel(self):
 | 
			
		||||
        self._log_skip_state_transition("cancel")
 | 
			
		||||
    def cancel_print(self):
 | 
			
		||||
        self._log_skip_state_transition("cancel_print")
 | 
			
		||||
 | 
			
		||||
    def resume(self):
 | 
			
		||||
        self._log_skip_state_transition("resume")
 | 
			
		||||
    def resume_print(self):
 | 
			
		||||
        self._log_skip_state_transition("resume_print")
 | 
			
		||||
 | 
			
		||||
    def _log_skip_state_transition(self, method):
 | 
			
		||||
        self._log.debug(f"skipping {self.__class__.__name__} state transition {method}")
 | 
			
		||||
        self._log.debug(
 | 
			
		||||
            f"skipping {self.__class__.__name__} state transition for '{method}'"
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
@@ -4,4 +4,50 @@ from octoprint_bambu_printer.printer.states.a_printer_state import APrinterState
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IdleState(APrinterState):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
    def start_new_print(self):
 | 
			
		||||
        selected_file = self._printer.file_system.selected_file
 | 
			
		||||
        if selected_file is None:
 | 
			
		||||
            self._log.warn("Cannot start print job if file was not selected")
 | 
			
		||||
            self._printer.change_state(self._printer._state_idle)
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        print_command = self._get_print_command_for_file(selected_file)
 | 
			
		||||
        if self._printer.bambu_client.publish(print_command):
 | 
			
		||||
            self._log.info(f"Started print for {selected_file.file_name}")
 | 
			
		||||
            self._printer.change_state(self._printer._state_printing)
 | 
			
		||||
        else:
 | 
			
		||||
            self._log.warn(f"Failed to start print for {selected_file.file_name}")
 | 
			
		||||
            self._printer.change_state(self._printer._state_idle)
 | 
			
		||||
 | 
			
		||||
    def _get_print_command_for_file(self, selected_file):
 | 
			
		||||
        print_command = {
 | 
			
		||||
            "print": {
 | 
			
		||||
                "sequence_id": 0,
 | 
			
		||||
                "command": "project_file",
 | 
			
		||||
                "param": "Metadata/plate_1.gcode",
 | 
			
		||||
                "md5": "",
 | 
			
		||||
                "profile_id": "0",
 | 
			
		||||
                "project_id": "0",
 | 
			
		||||
                "subtask_id": "0",
 | 
			
		||||
                "task_id": "0",
 | 
			
		||||
                "subtask_name": f"{selected_file}",
 | 
			
		||||
                "file": f"{selected_file}",
 | 
			
		||||
                "url": (
 | 
			
		||||
                    f"file:///mnt/sdcard/{selected_file}"
 | 
			
		||||
                    if self._printer._settings.get_boolean(["device_type"])
 | 
			
		||||
                    in ["X1", "X1C"]
 | 
			
		||||
                    else f"file:///sdcard/{selected_file}"
 | 
			
		||||
                ),
 | 
			
		||||
                "timelapse": self._printer._settings.get_boolean(["timelapse"]),
 | 
			
		||||
                "bed_leveling": self._printer._settings.get_boolean(["bed_leveling"]),
 | 
			
		||||
                "flow_cali": self._printer._settings.get_boolean(["flow_cali"]),
 | 
			
		||||
                "vibration_cali": self._printer._settings.get_boolean(
 | 
			
		||||
                    ["vibration_cali"]
 | 
			
		||||
                ),
 | 
			
		||||
                "layer_inspect": self._printer._settings.get_boolean(["layer_inspect"]),
 | 
			
		||||
                "use_ams": self._printer._settings.get_boolean(["use_ams"]),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return print_command
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ class PrintingState(APrinterState):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, printer: BambuVirtualPrinter) -> None:
 | 
			
		||||
        super().__init__(printer)
 | 
			
		||||
        self._printingLock = threading.Event()
 | 
			
		||||
        self._printing_lock = threading.Event()
 | 
			
		||||
        self._print_job: PrintJob | None = None
 | 
			
		||||
        self._sd_printing_thread = None
 | 
			
		||||
 | 
			
		||||
@@ -31,20 +31,22 @@ class PrintingState(APrinterState):
 | 
			
		||||
        return self._print_job
 | 
			
		||||
 | 
			
		||||
    def init(self):
 | 
			
		||||
        if not self._printingLock.is_set():
 | 
			
		||||
            self._printingLock.set()
 | 
			
		||||
        self._printing_lock.set()
 | 
			
		||||
        self.update_print_job_info()
 | 
			
		||||
        self._start_worker_thread()
 | 
			
		||||
 | 
			
		||||
    def finalize(self):
 | 
			
		||||
        if self._printingLock.is_set():
 | 
			
		||||
            self._printingLock.clear()
 | 
			
		||||
        self._printing_lock.clear()
 | 
			
		||||
 | 
			
		||||
    def _start_worker_thread(self, from_printer: bool = False):
 | 
			
		||||
        if self._sd_printing_thread is not None and self._sd_printing_thread.is_alive():
 | 
			
		||||
            self._sd_printing_thread.join()
 | 
			
		||||
            self._sd_printing_thread = None
 | 
			
		||||
 | 
			
		||||
    def _start_worker_thread(self):
 | 
			
		||||
        if self._sd_printing_thread is None:
 | 
			
		||||
            self._sdPrinting = True
 | 
			
		||||
            self._sdPrintStarting = True
 | 
			
		||||
            self._sd_printing_thread = threading.Thread(
 | 
			
		||||
                target=self._printing_worker, kwargs={"from_printer": from_printer}
 | 
			
		||||
            )
 | 
			
		||||
            if not self._printing_lock.is_set():
 | 
			
		||||
                self._printing_lock.set()
 | 
			
		||||
            self._sd_printing_thread = threading.Thread(target=self._printing_worker)
 | 
			
		||||
            self._sd_printing_thread.start()
 | 
			
		||||
 | 
			
		||||
    def update_print_job_info(self):
 | 
			
		||||
@@ -55,88 +57,52 @@ class PrintingState(APrinterState):
 | 
			
		||||
        )
 | 
			
		||||
        if project_file_info is None:
 | 
			
		||||
            self._log.debug(f"No 3mf file found for {print_job_info}")
 | 
			
		||||
            self._print_job = None
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if self._printer.file_system.select_file(filename):
 | 
			
		||||
            self._printer.sendOk()
 | 
			
		||||
        self.start_new_print(from_printer=True)
 | 
			
		||||
 | 
			
		||||
        # fuzzy math here to get print percentage to match BambuStudio
 | 
			
		||||
        progress = print_job_info.get("print_percentage")
 | 
			
		||||
        self._print_job = PrintJob(project_file_info, 0)
 | 
			
		||||
        self._print_job.progress = progress
 | 
			
		||||
 | 
			
		||||
    def start_new_print(self, from_printer: bool = False):
 | 
			
		||||
        if self._printer.file_system.selected_file is not None:
 | 
			
		||||
            self._start_worker_thread(from_printer)
 | 
			
		||||
 | 
			
		||||
        if self._sd_printing_thread is not None:
 | 
			
		||||
            if self._printer.bambu_client.connected:
 | 
			
		||||
                if self._printer.bambu_client.publish(pybambu.commands.RESUME):
 | 
			
		||||
                    self._log.info("print resumed")
 | 
			
		||||
                else:
 | 
			
		||||
                    self._log.info("print resume failed")
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def _printing_worker(self, from_printer: bool = False):
 | 
			
		||||
        try:
 | 
			
		||||
            if not from_printer and self._printer.bambu_client.connected:
 | 
			
		||||
                selected_file = self._printer.file_system.selected_file
 | 
			
		||||
                print_command = {
 | 
			
		||||
                    "print": {
 | 
			
		||||
                        "sequence_id": 0,
 | 
			
		||||
                        "command": "project_file",
 | 
			
		||||
                        "param": "Metadata/plate_1.gcode",
 | 
			
		||||
                        "md5": "",
 | 
			
		||||
                        "profile_id": "0",
 | 
			
		||||
                        "project_id": "0",
 | 
			
		||||
                        "subtask_id": "0",
 | 
			
		||||
                        "task_id": "0",
 | 
			
		||||
                        "subtask_name": f"{selected_file}",
 | 
			
		||||
                        "file": f"{selected_file}",
 | 
			
		||||
                        "url": (
 | 
			
		||||
                            f"file:///mnt/sdcard/{selected_file}"
 | 
			
		||||
                            if self._printer._settings.get_boolean(["device_type"])
 | 
			
		||||
                            in ["X1", "X1C"]
 | 
			
		||||
                            else f"file:///sdcard/{selected_file}"
 | 
			
		||||
                        ),
 | 
			
		||||
                        "timelapse": self._printer._settings.get_boolean(["timelapse"]),
 | 
			
		||||
                        "bed_leveling": self._printer._settings.get_boolean(
 | 
			
		||||
                            ["bed_leveling"]
 | 
			
		||||
                        ),
 | 
			
		||||
                        "flow_cali": self._printer._settings.get_boolean(["flow_cali"]),
 | 
			
		||||
                        "vibration_cali": self._printer._settings.get_boolean(
 | 
			
		||||
                            ["vibration_cali"]
 | 
			
		||||
                        ),
 | 
			
		||||
                        "layer_inspect": self._printer._settings.get_boolean(
 | 
			
		||||
                            ["layer_inspect"]
 | 
			
		||||
                        ),
 | 
			
		||||
                        "use_ams": self._printer._settings.get_boolean(["use_ams"]),
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                self._printer.bambu_client.publish(print_command)
 | 
			
		||||
 | 
			
		||||
            while self._print_job.file_position < self._print_job.file_info.size:
 | 
			
		||||
                if self._printer.is_running:
 | 
			
		||||
                    break
 | 
			
		||||
 | 
			
		||||
                self._printingLock.wait()
 | 
			
		||||
    def _printing_worker(self):
 | 
			
		||||
        if self._print_job is not None:
 | 
			
		||||
            while (
 | 
			
		||||
                self._printer.is_running
 | 
			
		||||
                and self._print_job.file_info is not None
 | 
			
		||||
                and self._print_job.file_position < self._print_job.file_info.size
 | 
			
		||||
            ):
 | 
			
		||||
                self.update_print_job_info()
 | 
			
		||||
                self._printer.report_print_job_status()
 | 
			
		||||
                time.sleep(3)
 | 
			
		||||
            self._log.debug(f"SD File Print: {self._selectedSdFile}")
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            if self.outgoing is not None:
 | 
			
		||||
                raise
 | 
			
		||||
 | 
			
		||||
                self._printing_lock.wait()
 | 
			
		||||
            self._log.debug(
 | 
			
		||||
                f"SD File Print finishing: {self._print_job.file_info.file_name}"
 | 
			
		||||
            )
 | 
			
		||||
        self._printer.change_state(self._printer._state_finished)
 | 
			
		||||
 | 
			
		||||
    def cancel(self):
 | 
			
		||||
    def pause_print(self):
 | 
			
		||||
        if self._printer.bambu_client.connected:
 | 
			
		||||
            if self._printer.bambu_client.publish(pybambu.commands.PAUSE):
 | 
			
		||||
                self._log.info("print paused")
 | 
			
		||||
                self._printer.change_state(self._printer._state_finished)
 | 
			
		||||
            else:
 | 
			
		||||
                self._log.info("print pause failed")
 | 
			
		||||
 | 
			
		||||
    def resume_print(self):
 | 
			
		||||
        if self._printer.bambu_client.connected:
 | 
			
		||||
            if self._printer.bambu_client.publish(pybambu.commands.RESUME):
 | 
			
		||||
                self._log.info("print resumed")
 | 
			
		||||
            else:
 | 
			
		||||
                self._log.info("print resume failed")
 | 
			
		||||
 | 
			
		||||
    def cancel_print(self):
 | 
			
		||||
        if self._printer.bambu_client.connected:
 | 
			
		||||
            if self._printer.bambu_client.publish(pybambu.commands.STOP):
 | 
			
		||||
                self._log.info("print cancelled")
 | 
			
		||||
                self._printer.change_state(self._printer._state_finished)
 | 
			
		||||
                return True
 | 
			
		||||
            else:
 | 
			
		||||
                self._log.info("print cancel failed")
 | 
			
		||||
                return False
 | 
			
		||||
        return False
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user