Skip to content

Commit

Permalink
Handle the new re-print LCD menu item in FW 3.14
Browse files Browse the repository at this point in the history
  • Loading branch information
TojikCZ committed Nov 27, 2023
1 parent dccf119 commit 5cb9596
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 1 deletion.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Periodically send a keepalive gcode to keep the printer in PrusaLink mode
* Support the set ready and cancel ready LCD menu toggle
* Add gcodes that flag the state of a usb print for the printer statistics to get saved
* Handle the new re-print LCD menu item

0.7.1rc1 (2023-08-10)
* Fixed HTTP response status on HEAD request for non-existing files
Expand Down
25 changes: 25 additions & 0 deletions prusa/link/printer_adapter/command_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from ..serial.helpers import enqueue_instruction, enqueue_list_from_str
from ..util import file_is_on_sd, round_to_five
from .command import Command, CommandFailed, FileNotFound, NotStateToPrint
from .model import Model
from .state_manager import StateChange
from .structures.model_classes import JobState
from .structures.regular_expressions import (
Expand Down Expand Up @@ -555,3 +556,27 @@ def _run_command(self):
default_source=self.source))
self.state_manager.idle()
self.state_manager.stop_expecting_change()


class RePrint(StartPrint):
"""Class for starting the last job again"""
command_name = "re-print"

def __init__(self, **kwargs):
# Need to get the model sooner than it's available in self
model = Model.get_instance()
path = model.job.last_job_path
if path is None:
path = ""
super().__init__(path=path, **kwargs)

def _run_command(self):
"""Re-prints the last job, makes a noise and sends an LCD message
if that fails"""
try:
super()._run_command()
except CommandFailed as exception:
# Not an ideal way to do this, but less time-consuming
enqueue_instruction(self.serial_queue, "M300 P200 S600")
enqueue_instruction(self.serial_queue, "M117 \x7ECannot re-print")
raise exception
11 changes: 10 additions & 1 deletion prusa/link/printer_adapter/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def __init__(self,
printing_file_byte=None,
job_state=JobState.IDLE,
job_id=None,
job_id_offset=0)
job_id_offset=0,
last_job_path=None)
self.data = self.model.job

self.job_id_updated_signal.send(self,
Expand Down Expand Up @@ -100,6 +101,7 @@ def job_started(self, command_id=None):
self.model.print_stats.has_inbuilt_stats
self.change_state(JobState.IN_PROGRESS)
self.write()
self.update_last_job_path()
log.debug("New job started, id = %s", self.data.job_id)
self.job_id_updated_signal.send(self,
job_id=self.data.get_job_id_for_api())
Expand Down Expand Up @@ -192,8 +194,15 @@ def set_file_path(self, path, path_incomplete, prepend_sd_storage):
self.data.selected_file_size = file_obj.attrs["size"]
self.model.job.from_sd = path.startswith(
os.path.join("/", SD_STORAGE_NAME))
self.update_last_job_path()
self.job_info_updated()

def update_last_job_path(self):
"""Updates the last job path to be used for the re-print menu item"""
if self.data.job_state != JobState.IN_PROGRESS:
return
self.data.last_job_path = self.data.selected_file_path

def get_job_info_data(self, for_connect=False):
"""Compiles the job info data into a dict"""
if for_connect:
Expand Down
12 changes: 12 additions & 0 deletions prusa/link/printer_adapter/prusa_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
JobInfo,
LoadFilament,
PausePrint,
RePrint,
ResetPrinter,
ResumePrint,
SetReady,
Expand Down Expand Up @@ -86,6 +87,7 @@
NOT_READY_REGEX,
PAUSE_PRINT_REGEX,
PRINTER_BOOT_REGEX,
REPRINT_REGEX,
READY_REGEX,
RESUME_PRINT_REGEX,
TM_CAL_END_REGEX,
Expand Down Expand Up @@ -196,6 +198,8 @@ def __init__(self, cfg: Config, settings: Settings) -> None:
READY_REGEX, lambda sender, match: self.fw_set_ready())
self.serial_parser.add_decoupled_handler(
NOT_READY_REGEX, lambda sender, match: self.fw_cancel_ready())
self.serial_parser.add_decoupled_handler(
REPRINT_REGEX, lambda sender, match: self.fw_reprint())

# Init components first, so they all exist for signal binding stuff
# TODO: does not need printer, the transfer object should be
Expand Down Expand Up @@ -362,6 +366,8 @@ def debug_shell(self) -> None:
result: Any = ""
if command == "pause":
result = self.command_queue.do_command(PausePrint())
elif command == "reprint":
result = self.command_queue.do_command(RePrint())
elif command == "resume":
result = self.command_queue.do_command(ResumePrint())
elif command == "stop":
Expand Down Expand Up @@ -600,6 +606,12 @@ def fw_cancel_ready(self) -> None:
command = CancelReady(source=Source.USER)
self.command_queue.enqueue_command(command)

def fw_reprint(self) -> None:
"""Prints the last job again, activated from the printer LCD screen"""
prctl_name()
command = RePrint(source=Source.USER)
self.command_queue.enqueue_command(command)

# --- Signal handlers ---
def layer_trigger(self, _):
"""Passes the call to trigger to the camera controller"""
Expand Down
2 changes: 2 additions & 0 deletions prusa/link/printer_adapter/structures/module_data_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class JobData(BaseModel):
from_sd: Optional[bool]
inbuilt_reporting: Optional[bool]

last_job_path: Optional[str]

job_state: JobState

def get_job_id_for_api(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
CANCEL_REGEX = re.compile("^// action:cancel$")
READY_REGEX = re.compile("^// action:ready$")
NOT_READY_REGEX = re.compile("^// action:not_ready$")
REPRINT_REGEX = re.compile("^// action:reprint$")
# This girthy regexp tries to capture all error messages requiring printer
# reset using M999 or manual button, with connect, only manual reset shall
# be accepted
Expand Down
2 changes: 2 additions & 0 deletions prusa/link/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ def get_gcode(line):

def file_is_on_sd(path_parts):
"""Checks if the file path starts wit the sd cards' storage name"""
if len(path_parts) < 2:
return False
return path_parts[1] == SD_STORAGE_NAME


Expand Down

0 comments on commit 5cb9596

Please sign in to comment.