aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/extras/palette2.py
diff options
context:
space:
mode:
Diffstat (limited to 'klippy/extras/palette2.py')
-rw-r--r--klippy/extras/palette2.py212
1 files changed, 104 insertions, 108 deletions
diff --git a/klippy/extras/palette2.py b/klippy/extras/palette2.py
index 4fe72080..1679eec3 100644
--- a/klippy/extras/palette2.py
+++ b/klippy/extras/palette2.py
@@ -23,19 +23,20 @@ COMMAND_CLEAR = [
"O10 D1 D0 D0 DFFE1",
"O10 D2 D0 D0 DFFE1",
"O10 D3 D0 D0 DFFE1",
- "O10 D4 D0 D0 D0069"]
+ "O10 D4 D0 D0 D0069",
+]
COMMAND_FILENAME = "O51"
COMMAND_FILENAMES_DONE = "O52"
COMMAND_FIRMWARE = "O50"
COMMAND_PING = "O31"
COMMAND_SMART_LOAD_STOP = "O102 D1"
-HEARTBEAT_SEND = 5.
-HEARTBEAT_TIMEOUT = (HEARTBEAT_SEND * 2.) + 1.
+HEARTBEAT_SEND = 5.0
+HEARTBEAT_TIMEOUT = (HEARTBEAT_SEND * 2.0) + 1.0
SETUP_TIMEOUT = 10
SERIAL_TIMER = 0.1
-AUTOLOAD_TIMER = 5.
+AUTOLOAD_TIMER = 5.0
INFO_NOT_CONNECTED = "Palette 2 is not connected, connect first"
@@ -45,54 +46,56 @@ class Palette2:
self.printer = config.get_printer()
self.reactor = self.printer.get_reactor()
try:
- self.virtual_sdcard = self.printer.load_object(
- config, "virtual_sdcard")
+ self.virtual_sdcard = self.printer.load_object(config, "virtual_sdcard")
except config.error:
raise self.printer.config_error(
"Palette 2 requires [virtual_sdcard] to work,"
- " please add it to your config!")
+ " please add it to your config!"
+ )
try:
- self.pause_resume = self.printer.load_object(
- config, "pause_resume")
+ self.pause_resume = self.printer.load_object(config, "pause_resume")
except config.error:
raise self.printer.config_error(
"Palette 2 requires [pause_resume] to work,"
- " please add it to your config!")
- self.gcode_move = self.printer.load_object(config, 'gcode_move')
+ " please add it to your config!"
+ )
+ self.gcode_move = self.printer.load_object(config, "gcode_move")
self.gcode = self.printer.lookup_object("gcode")
self.gcode.register_command(
- "PALETTE_CONNECT", self.cmd_Connect, desc=self.cmd_Connect_Help)
+ "PALETTE_CONNECT", self.cmd_Connect, desc=self.cmd_Connect_Help
+ )
self.gcode.register_command(
- "PALETTE_DISCONNECT",
- self.cmd_Disconnect,
- desc=self.cmd_Disconnect_Help)
+ "PALETTE_DISCONNECT", self.cmd_Disconnect, desc=self.cmd_Disconnect_Help
+ )
self.gcode.register_command(
- "PALETTE_CLEAR", self.cmd_Clear, desc=self.cmd_Clear_Help)
+ "PALETTE_CLEAR", self.cmd_Clear, desc=self.cmd_Clear_Help
+ )
+ self.gcode.register_command("PALETTE_CUT", self.cmd_Cut, desc=self.cmd_Cut_Help)
self.gcode.register_command(
- "PALETTE_CUT", self.cmd_Cut, desc=self.cmd_Cut_Help)
- self.gcode.register_command(
- "PALETTE_SMART_LOAD",
- self.cmd_Smart_Load,
- desc=self.cmd_Smart_Load_Help)
+ "PALETTE_SMART_LOAD", self.cmd_Smart_Load, desc=self.cmd_Smart_Load_Help
+ )
self.serial = None
self.serial_port = config.get("serial")
if not self.serial_port:
raise config.error("Invalid serial port specific for Palette 2")
self.baud = config.getint("baud", default=115200)
self.feedrate_splice = config.getfloat(
- "feedrate_splice", default=0.8, minval=0., maxval=1.)
+ "feedrate_splice", default=0.8, minval=0.0, maxval=1.0
+ )
self.feedrate_normal = config.getfloat(
- "feedrate_normal", default=1.0, minval=0., maxval=1.)
+ "feedrate_normal", default=1.0, minval=0.0, maxval=1.0
+ )
self.auto_load_speed = config.getint("auto_load_speed", 2)
self.auto_cancel_variation = config.getfloat(
- "auto_cancel_variation", default=None, minval=0.01, maxval=0.2)
+ "auto_cancel_variation", default=None, minval=0.01, maxval=0.2
+ )
# Omega code matchers
self.omega_header = [None] * 9
omega_handlers = ["O" + str(i) for i in range(33)]
for cmd in omega_handlers:
- func = getattr(self, 'cmd_' + cmd, None)
- desc = getattr(self, 'cmd_' + cmd + '_help', None)
+ func = getattr(self, "cmd_" + cmd, None)
+ desc = getattr(self, "cmd_" + cmd + "_help", None)
if func:
self.gcode.register_command(cmd, func, desc=desc)
else:
@@ -137,20 +140,24 @@ class Palette2:
gcmd.respond_info(INFO_NOT_CONNECTED)
return False
- cmd_Connect_Help = ("Connect to the Palette 2")
+ cmd_Connect_Help = "Connect to the Palette 2"
def cmd_Connect(self, gcmd):
if self.serial:
gcmd.respond_info(
- "Palette 2 serial port is already active, disconnect first")
+ "Palette 2 serial port is already active, disconnect first"
+ )
return
self.signal_disconnect = False
- logging.info("Connecting to Palette 2 on port (%s) at (%s)" %
- (self.serial_port, self.baud))
+ logging.info(
+ "Connecting to Palette 2 on port (%s) at (%s)"
+ % (self.serial_port, self.baud)
+ )
try:
self.serial = serial.Serial(
- self.serial_port, self.baud, timeout=0, write_timeout=0)
+ self.serial_port, self.baud, timeout=0, write_timeout=0
+ )
except SerialException:
gcmd.respond_info("Unable to connect to the Palette 2")
return
@@ -160,19 +167,20 @@ class Palette2:
with self.read_queue.mutex:
self.read_queue.queue.clear()
- self.read_timer = self.reactor.register_timer(
- self._run_Read, self.reactor.NOW)
+ self.read_timer = self.reactor.register_timer(self._run_Read, self.reactor.NOW)
self.write_timer = self.reactor.register_timer(
- self._run_Write, self.reactor.NOW)
+ self._run_Write, self.reactor.NOW
+ )
self.heartbeat_timer = self.reactor.register_timer(
- self._run_Heartbeat, self.reactor.NOW)
+ self._run_Heartbeat, self.reactor.NOW
+ )
# Tell the device we're alive
self.write_queue.put("\n")
self.write_queue.put(COMMAND_FIRMWARE)
self._wait_for_heartbeat()
- cmd_Disconnect_Help = ("Disconnect from the Palette 2")
+ cmd_Disconnect_Help = "Disconnect from the Palette 2"
def cmd_Disconnect(self, gcmd=None):
self.gcode.respond_info("Disconnecting from Palette 2")
@@ -188,7 +196,7 @@ class Palette2:
self.heartbeat = None
self.is_printing = False
- cmd_Clear_Help = ("Clear the input and output of the Palette 2")
+ cmd_Clear_Help = "Clear the input and output of the Palette 2"
def cmd_Clear(self, gcmd):
logging.info("Clearing Palette 2 input and output")
@@ -196,20 +204,19 @@ class Palette2:
for l in COMMAND_CLEAR:
self.write_queue.put(l)
- cmd_Cut_Help = ("Cut the outgoing filament")
+ cmd_Cut_Help = "Cut the outgoing filament"
def cmd_Cut(self, gcmd):
logging.info("Cutting outgoing filament in Palette 2")
if self._check_P2(gcmd):
self.write_queue.put(COMMAND_CUT)
- cmd_Smart_Load_Help = ("Automatically load filament through the extruder")
+ cmd_Smart_Load_Help = "Automatically load filament through the extruder"
def cmd_Smart_Load(self, gcmd):
if self._check_P2(gcmd):
if not self.is_loading:
- gcmd.respond_info(
- "Cannot auto load when the Palette 2 is not ready")
+ gcmd.respond_info("Cannot auto load when the Palette 2 is not ready")
return
self.p2cmd_O102(params=None)
@@ -221,33 +228,32 @@ class Palette2:
def _wait_for_heartbeat(self):
startTs = self.reactor.monotonic()
currTs = startTs
- while self.heartbeat is None or (self.heartbeat < (
- currTs - SETUP_TIMEOUT) and startTs > (
- currTs - SETUP_TIMEOUT)):
- currTs = self.reactor.pause(currTs + 1.)
+ while self.heartbeat is None or (
+ self.heartbeat < (currTs - SETUP_TIMEOUT)
+ and startTs > (currTs - SETUP_TIMEOUT)
+ ):
+ currTs = self.reactor.pause(currTs + 1.0)
if self.heartbeat < (currTs - SETUP_TIMEOUT):
self.signal_disconnect = True
- raise self.printer.command_error(
- "No response from Palette 2")
+ raise self.printer.command_error("No response from Palette 2")
- cmd_O1_help = (
- "Initialize the print, and check connection with the Palette 2")
+ cmd_O1_help = "Initialize the print, and check connection with the Palette 2"
def cmd_O1(self, gcmd):
logging.info("Initializing print with Palette 2")
if not self._check_P2(gcmd):
raise self.printer.command_error(
- "Cannot initialize print, palette 2 is not connected")
+ "Cannot initialize print, palette 2 is not connected"
+ )
self.reactor.update_timer(self.heartbeat_timer, self.reactor.NOW)
self._wait_for_heartbeat()
self.write_queue.put(gcmd.get_commandline())
- self.gcode.respond_info(
- "Palette 2 waiting on user to complete setup")
+ self.gcode.respond_info("Palette 2 waiting on user to complete setup")
self.pause_resume.send_pause_command()
- cmd_O9_help = ("Reset print information")
+ cmd_O9_help = "Reset print information"
def cmd_O9(self, gcmd):
logging.info("Print finished, resetting Palette 2 state")
@@ -305,20 +311,19 @@ class Palette2:
param_drive = gcmd.get_commandline()[5:6]
param_distance = gcmd.get_commandline()[8:]
except IndexError:
- gcmd.respond_info(
- "Incorrect number of arguments for splice command")
+ gcmd.respond_info("Incorrect number of arguments for splice command")
try:
self.omega_splices.append((int(param_drive), param_distance))
except ValueError:
gcmd.respond_info("Incorrectly formatted splice command")
- logging.debug("Omega splice command drive %s distance %s" %
- (param_drive, param_distance))
+ logging.debug(
+ "Omega splice command drive %s distance %s" % (param_drive, param_distance)
+ )
def cmd_O31(self, gcmd):
if self._check_P2(gcmd):
self.omega_current_ping = gcmd.get_commandline()
- logging.debug("Omega ping command: %s" %
- (gcmd.get_commandline()))
+ logging.debug("Omega ping command: %s" % (gcmd.get_commandline()))
self.write_queue.put(COMMAND_PING)
self.gcode.create_gcode_command("G4", "G4", {"P": "10"})
@@ -352,14 +357,11 @@ class Palette2:
self.write_queue.put("O30 D%d D%s" % (splice[0], splice[1]))
self.omega_splices_counter = self.omega_splices_counter + 1
elif n == 2:
- logging.info("Sending current ping info %s" %
- self.omega_current_ping)
+ logging.info("Sending current ping info %s" % self.omega_current_ping)
self.write_queue.put(self.omega_current_ping)
elif n == 4:
- logging.info("Sending algorithm info %s" %
- self.omega_algorithms_counter)
- self.write_queue.put(
- self.omega_algorithms[self.omega_algorithms_counter])
+ logging.info("Sending algorithm info %s" % self.omega_algorithms_counter)
+ self.write_queue.put(self.omega_algorithms[self.omega_algorithms_counter])
self.omega_algorithms_counter = self.omega_algorithms_counter + 1
elif n == 8:
logging.info("Resending the last command to Palette 2")
@@ -371,11 +373,10 @@ class Palette2:
def check_ping_variation(last_ping):
if self.auto_cancel_variation is not None:
- ping_max = 100. + (self.auto_cancel_variation * 100.)
- ping_min = 100. - (self.auto_cancel_variation * 100.)
+ ping_max = 100.0 + (self.auto_cancel_variation * 100.0)
+ ping_min = 100.0 - (self.auto_cancel_variation * 100.0)
if last_ping < ping_min or last_ping > ping_max:
- logging.info("Ping variation is too high, "
- "cancelling print")
+ logging.info("Ping variation is too high, " "cancelling print")
self.gcode.run_script("CANCEL_PRINT")
if len(params) > 2:
@@ -400,21 +401,22 @@ class Palette2:
if len(params) > 1:
try:
fw = params[0][1:]
- logging.info(
- "Palette 2 firmware version %s detected" % fw)
+ logging.info("Palette 2 firmware version %s detected" % fw)
except (TypeError, IndexError):
logging.error("Unable to parse firmware version")
if fw < "9.0.9":
raise self.printer.command_error(
- "Palette 2 firmware version is too old, "
- "update to at least 9.0.9")
+ "Palette 2 firmware version is too old, " "update to at least 9.0.9"
+ )
else:
self.files = [
- file for (
- file,
- size) in self.virtual_sdcard.get_file_list(
- check_subdirs=True) if ".mcf.gcode" in file]
+ file
+ for (file, size) in self.virtual_sdcard.get_file_list(
+ check_subdirs=True
+ )
+ if ".mcf.gcode" in file
+ ]
for file in self.files:
self.write_queue.put("%s D%s" % (COMMAND_FILENAME, file))
self.write_queue.put(COMMAND_FILENAMES_DONE)
@@ -452,8 +454,7 @@ class Palette2:
def loadingOffset(params):
self.remaining_load_length = int(params[1][1:])
- logging.debug("Loading filamant remaining %d" %
- self.remaining_load_length)
+ logging.debug("Loading filamant remaining %d" % self.remaining_load_length)
if self.remaining_load_length >= 0 and self.smart_load_timer:
logging.info("Smart load filament is complete")
self.reactor.unregister_timer(self.smart_load_timer)
@@ -461,14 +462,12 @@ class Palette2:
self.is_loading = False
def feedrateStart(params):
- logging.info("Setting feedrate to %f for splice" %
- self.feedrate_splice)
+ logging.info("Setting feedrate to %f for splice" % self.feedrate_splice)
self.is_splicing = True
self.gcode.run_script("M220 S%d" % (self.feedrate_splice * 100))
def feedrateEnd(params):
- logging.info("Setting feedrate to %f splice done" %
- self.feedrate_normal)
+ logging.info("Setting feedrate to %f splice done" % self.feedrate_normal)
self.is_splicing = False
self.gcode.run_script("M220 S%d" % (self.feedrate_normal * 100))
@@ -495,13 +494,15 @@ class Palette2:
if not toolhead.get_extruder().get_heater().can_extrude:
self.write_queue.put(COMMAND_SMART_LOAD_STOP)
self.gcode.respond_info(
- "Unable to auto load filament, extruder is below minimum temp")
+ "Unable to auto load filament, extruder is below minimum temp"
+ )
return
if self.smart_load_timer is None:
logging.info("Smart load starting")
self.smart_load_timer = self.reactor.register_timer(
- self._run_Smart_Load, self.reactor.NOW)
+ self._run_Smart_Load, self.reactor.NOW
+ )
def p2cmd(self, line):
t = line.split()
@@ -514,7 +515,7 @@ class Palette2:
logging.error("Omega parameters are invalid")
return
- func = getattr(self, 'p2cmd_' + ocode, None)
+ func = getattr(self, "p2cmd_" + ocode, None)
if func is not None:
func(params)
@@ -523,8 +524,9 @@ class Palette2:
for matcher in matchers:
if len(params) >= matcher[1]:
match_params = matcher[2:]
- res = all([match_params[i] == params[i]
- for i in range(len(match_params))])
+ res = all(
+ [match_params[i] == params[i] for i in range(len(match_params))]
+ )
if res:
matcher[0](params)
return True
@@ -544,15 +546,14 @@ class Palette2:
self.cmd_Disconnect()
return self.reactor.NEVER
if len(raw_bytes):
- new_buffer = str(raw_bytes.decode(encoding='UTF-8',
- errors='ignore'))
+ new_buffer = str(raw_bytes.decode(encoding="UTF-8", errors="ignore"))
text_buffer = self.read_buffer + new_buffer
while True:
i = text_buffer.find("\n")
if i >= 0:
- line = text_buffer[0:i + 1]
+ line = text_buffer[0 : i + 1]
self.read_queue.put(line.strip())
- text_buffer = text_buffer[i + 1:]
+ text_buffer = text_buffer[i + 1 :]
else:
break
self.read_buffer = text_buffer
@@ -582,10 +583,8 @@ class Palette2:
def _run_Heartbeat(self, eventtime):
self.write_queue.put(COMMAND_HEARTBEAT)
eventtime = self.reactor.pause(eventtime + 5)
- if self.heartbeat and self.heartbeat < (
- eventtime - HEARTBEAT_TIMEOUT):
- logging.error(
- "P2 has not responded to heartbeat")
+ if self.heartbeat and self.heartbeat < (eventtime - HEARTBEAT_TIMEOUT):
+ logging.error("P2 has not responded to heartbeat")
if not self.is_printing or self.is_setup_complete:
self.cmd_Disconnect()
return self.reactor.NEVER
@@ -602,9 +601,7 @@ class Palette2:
self.omega_last_command = text_line
l = text_line.strip()
if COMMAND_HEARTBEAT not in l:
- logging.debug(
- "%s -> P2 : %s" %
- (self.reactor.monotonic(), l))
+ logging.debug("%s -> P2 : %s" % (self.reactor.monotonic(), l))
terminated_line = "%s\n" % (l)
try:
self.serial.write(terminated_line.encode())
@@ -619,23 +616,22 @@ class Palette2:
if not self.is_splicing and self.remaining_load_length < 0:
# Make sure toolhead class isn't busy
toolhead = self.printer.lookup_object("toolhead")
- print_time, est_print_time, lookahead_empty = toolhead.check_busy(
- eventtime)
+ print_time, est_print_time, lookahead_empty = toolhead.check_busy(eventtime)
idle_time = est_print_time - print_time
if not lookahead_empty or idle_time < 0.5:
- return eventtime + \
- max(0., min(1., print_time - est_print_time))
+ return eventtime + max(0.0, min(1.0, print_time - est_print_time))
extrude = abs(self.remaining_load_length)
extrude = min(50, extrude / 2)
if extrude <= 10:
extrude = 1
- logging.info("Smart loading %dmm filament with %dmm remaining" % (
- extrude, abs(self.remaining_load_length)))
+ logging.info(
+ "Smart loading %dmm filament with %dmm remaining"
+ % (extrude, abs(self.remaining_load_length))
+ )
self.gcode.run_script("G92 E0")
- self.gcode.run_script("G1 E%d F%d" % (
- extrude, self.auto_load_speed * 60))
+ self.gcode.run_script("G1 E%d F%d" % (extrude, self.auto_load_speed * 60))
return self.reactor.NOW
return eventtime + AUTOLOAD_TIMER
@@ -643,7 +639,7 @@ class Palette2:
status = {
"ping": None,
"remaining_load_length": self.remaining_load_length,
- "is_splicing": self.is_splicing
+ "is_splicing": self.is_splicing,
}
if self.omega_pings:
status["ping"] = self.omega_pings[-1]