Skip to content

Commit

Permalink
Add a delay after power panic, so the printer can reach pause state
Browse files Browse the repository at this point in the history
  • Loading branch information
TojikCZ committed May 3, 2024
1 parent 3cd2623 commit 67c1963
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 4 deletions.
2 changes: 2 additions & 0 deletions prusa/link/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@
PRINT_END_TIMEOUT = 11
KEEPALIVE_INTERVAL = 12

PP_MOVES_DELAY = 45

# --- Lcd queue ---
LCD_QUEUE_SIZE = 30

Expand Down
2 changes: 2 additions & 0 deletions prusa/link/printer_adapter/file_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def _print_end(self):
if self.data.power_panic:
return

os.remove(self.data.pp_file_path)
self.do_instruction("M77") # stop printer's print timer

self.data.printing = False
Expand Down Expand Up @@ -365,6 +366,7 @@ def write_file_stats(self, file_path, message_number, gcode_number):
connect_path=self.model.job.selected_file_path,
message_number=message_number,
gcode_number=gcode_number,
using_rip_port=self.model.serial_adapter.using_port.is_rpi_port,
)
with open(self.data.pp_file_path, "w", encoding="UTF-8") as pp_file:
pp_file.write(json.dumps(data.dict()))
Expand Down
6 changes: 5 additions & 1 deletion prusa/link/printer_adapter/prusa_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
get_print_stats_gcode,
is_potato_cpu,
make_fingerprint,
power_panic_delay,
prctl_name,
)
from .auto_telemetry import AutoTelemetry
Expand Down Expand Up @@ -120,7 +121,6 @@ class TransferCallbackState(Enum):
PRINTER_IN_ATTENTION = 3


# TODO: Can i somehow make subcontrollers to isolate some of the components?
class PrusaLink:
"""
This class is the controller for PrusaLink, more specifically the part
Expand All @@ -147,6 +147,9 @@ def __init__(self, cfg: Config, settings: Settings) -> None:

self.serial_parser = ThreadedSerialParser()

# Wait for power panic recovery to reach a stable state
power_panic_delay(cfg)

self.serial = SerialAdapter(
self.serial_parser,
self.model,
Expand Down Expand Up @@ -952,6 +955,7 @@ def power_panic_observed(self, *_, **__):
# This is normally a bad idea in a serial handler
# But as we are holding the serial disconnected anyways, it's OK
sleep(10)
power_panic_delay(self.cfg)
self.serial.power_panic_unblock()

def recover_from_pp(self, *_, **__) -> None:
Expand Down
1 change: 1 addition & 0 deletions prusa/link/printer_adapter/structures/model_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,4 @@ class PPData(BaseModel):
connect_path: str
message_number: int # N number on the printer
gcode_number: int # From file printer
using_rip_port: bool = False
33 changes: 30 additions & 3 deletions prusa/link/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Contains functions that might be useful outside of their modules"""
import datetime
import json
import logging
import multiprocessing
import os
Expand All @@ -10,16 +11,25 @@
from hashlib import sha256
from pathlib import Path
from threading import Event, current_thread
from time import time
from time import sleep, time
from typing import Callable

import prctl # type: ignore
import pyudev # type: ignore
import unidecode

from .const import MMU_SLOTS, SD_STORAGE_NAME, SUPPORTED_PRINTERS
from .const import (
MMU_SLOTS,
PP_MOVES_DELAY,
SD_STORAGE_NAME,
SUPPORTED_PRINTERS,
)
from .multi_instance.const import VALID_SN_REGEX
from .printer_adapter.structures.model_classes import IndividualSlot, Slot
from .printer_adapter.structures.model_classes import (
IndividualSlot,
PPData,
Slot,
)

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -315,3 +325,20 @@ def _parse_little_endian_uint32(match):
str_data = match.group("data").replace(" ", "")
data = bytes.fromhex(str_data)
return struct.unpack("<I", data)[0]


def power_panic_delay(cfg):
"""Adds a dynamic delay depending on power panic details.
This is needed so the printer reaches a stable state before we reset it."""
pp_file_path = cfg.daemon.power_panic_file
if not os.path.exists(pp_file_path):
return

with open(pp_file_path, "r", encoding="UTF-8") as pp_file:
pp_data = PPData(**json.load(pp_file))
if pp_data.using_rip_port:
return

log.info("Waiting an extra %ss for printer to heat up "
"and finish its moves", PP_MOVES_DELAY)
sleep(PP_MOVES_DELAY)

0 comments on commit 67c1963

Please sign in to comment.