aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--klippy/gcode.py17
-rw-r--r--klippy/klippy.py66
-rw-r--r--klippy/mcu.py5
3 files changed, 69 insertions, 19 deletions
diff --git a/klippy/gcode.py b/klippy/gcode.py
index 50743bc8..ff7e2443 100644
--- a/klippy/gcode.py
+++ b/klippy/gcode.py
@@ -109,7 +109,7 @@ class GCodeParser:
except:
logging.exception("Exception in command handler")
self.toolhead.force_shutdown()
- self.respond('Error: Internal error on command:"%s"' % (cmd,))
+ self.respond_error('Internal error on command:"%s"' % (cmd,))
# Check if machine can process next command or must stall input
if self.busy_state is not None:
break
@@ -146,6 +146,11 @@ class GCodeParser:
if self.is_fileinput:
return
os.write(self.fd, msg+"\n")
+ def respond_error(self, msg):
+ lines = msg.strip().split('\n')
+ for line in lines[:-1]:
+ self.respond('// %s' % (line.strip(),))
+ self.respond('!! %s' % (lines[-1].strip(),))
# Busy handling
def set_busy(self, busy_handler):
self.busy_state = busy_handler
@@ -154,12 +159,12 @@ class GCodeParser:
try:
busy = self.busy_state.check_busy(eventtime)
except homing.EndstopError, e:
- self.respond("Error: %s" % (e,))
+ self.respond_error(str(e))
busy = False
except:
logging.exception("Exception in busy handler")
self.toolhead.force_shutdown()
- self.respond('Error: Internal error in busy handler')
+ self.respond_error('Internal error in busy handler')
busy = False
if busy:
self.toolhead.reset_motor_off_time(eventtime)
@@ -208,7 +213,7 @@ class GCodeParser:
# Individual command handlers
def cmd_default(self, params):
if not self.is_printer_ready:
- self.respond('Error: Printer is not ready')
+ self.respond_error(self.printer.get_state_message())
return
cmd = params.get('#command')
if not cmd:
@@ -233,7 +238,7 @@ class GCodeParser:
try:
self.toolhead.move(self.last_position, self.speed, sloppy)
except homing.EndstopError, e:
- self.respond("Error: %s" % (e,))
+ self.respond_error(str(e))
self.last_position = self.toolhead.get_position()
def cmd_G4(self, params):
# Dwell
@@ -244,7 +249,7 @@ class GCodeParser:
self.toolhead.dwell(delay)
def cmd_G20(self, params):
# Set units to inches
- self.respond('Error: Machine does not support G20 (inches) command')
+ self.respond_error('Machine does not support G20 (inches) command')
def cmd_G21(self, params):
# Set units to millimeters
pass
diff --git a/klippy/klippy.py b/klippy/klippy.py
index 8850361d..088d81bb 100644
--- a/klippy/klippy.py
+++ b/klippy/klippy.py
@@ -7,6 +7,32 @@
import sys, optparse, ConfigParser, logging, time, threading
import gcode, toolhead, util, mcu, fan, heater, extruder, reactor, queuelogger
+message_startup = """
+The klippy host software is attempting to connect. Please
+retry in a few moments.
+Printer is not ready
+"""
+
+message_restart = """
+This is an unrecoverable error. Please correct the
+underlying issue and then manually restart the klippy host
+software.
+Printer is halted
+"""
+
+message_mcu_connect_error = """
+This is an unrecoverable error. Please manually restart
+both the firmware and the host software.
+Error configuring printer
+"""
+
+message_shutdown = """
+This is an unrecoverable error. Please correct the
+underlying issue and then manually restart both the
+firmware and the host software.
+Printer is shutdown
+"""
+
class ConfigWrapper:
def __init__(self, printer, section):
self.printer = printer
@@ -38,6 +64,7 @@ class Printer:
self.stats_timer = self.reactor.register_timer(self.stats)
self.connect_timer = self.reactor.register_timer(
self.connect, self.reactor.NOW)
+ self.state_message = message_startup
self.debugoutput = self.dictionary = None
self.fileconfig = None
self.mcu = None
@@ -74,23 +101,42 @@ class Printer:
self.gcode.build_config()
self.mcu.build_config()
def connect(self, eventtime):
- self.load_config()
- if self.debugoutput is None:
- self.reactor.update_timer(self.stats_timer, self.reactor.NOW)
- else:
- self.mcu.connect_file(self.debugoutput, self.dictionary)
- self.mcu.connect()
- self.build_config()
- self.gcode.set_printer_ready(True)
+ try:
+ self.load_config()
+ if self.debugoutput is None:
+ self.reactor.update_timer(self.stats_timer, self.reactor.NOW)
+ else:
+ self.mcu.connect_file(self.debugoutput, self.dictionary)
+ self.mcu.connect()
+ self.build_config()
+ self.gcode.set_printer_ready(True)
+ self.state_message = "Running"
+ except mcu.error, e:
+ logging.exception("MCU error during connect")
+ self.state_message = "%s%s" % (str(e), message_mcu_connect_error)
+ self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
+ except:
+ logging.exception("Unhandled exception during connect")
+ self.state_message = "Internal error during connect.%s" % (
+ message_restart)
+ self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
self.reactor.unregister_timer(self.connect_timer)
return self.reactor.NEVER
def run(self):
- self.reactor.run()
+ try:
+ self.reactor.run()
+ except:
+ logging.exception("Unhandled exception during run")
+ return
# If gcode exits, then exit the MCU
self.stats(time.time())
self.mcu.disconnect()
self.stats(time.time())
- def note_shutdown(self):
+ def get_state_message(self):
+ return self.state_message
+ def note_shutdown(self, msg):
+ self.state_message = "Firmware shutdown: %s%s" % (
+ msg, message_shutdown)
self.gcode.set_printer_ready(False)
diff --git a/klippy/mcu.py b/klippy/mcu.py
index 2e15287f..e039f2d5 100644
--- a/klippy/mcu.py
+++ b/klippy/mcu.py
@@ -336,7 +336,7 @@ class MCU:
self.is_shutdown = True
logging.info("%s: %s" % (params['#name'], params['#msg']))
self.serial.dump_debug()
- self._printer.note_shutdown()
+ self._printer.note_shutdown(params['#msg'])
# Connection phase
def connect(self):
if not self._is_fileoutput:
@@ -421,8 +421,7 @@ class MCU:
if not self._is_fileoutput:
config_params = self.serial.send_with_response(msg, 'config')
if self._config_crc != config_params['crc']:
- logging.error("Printer CRC does not match config")
- sys.exit(1)
+ raise error("Printer CRC does not match config")
logging.info("Configured")
stepqueues = tuple(s._stepqueue for s in self._steppers)
self._steppersync = self.ffi_lib.steppersync_alloc(