klippy: Add ability to restart the host software

Add a "restart" gcode command that will cause the host "klippy"
software to reload its config and restart.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2016-11-30 23:47:40 -05:00
parent a6055ce069
commit fbd7cc243b
2 changed files with 39 additions and 20 deletions

View File

@ -47,7 +47,7 @@ class GCodeParser:
def build_handlers(self):
handlers = ['G1', 'G4', 'G20', 'G21', 'G28', 'G90', 'G91', 'G92',
'M18', 'M82', 'M83', 'M105', 'M110', 'M114', 'M206',
'HELP', 'QUERY_ENDSTOPS']
'HELP', 'QUERY_ENDSTOPS', 'RESTART']
if self.heater_nozzle is not None:
handlers.extend(['M104', 'M109', 'PID_TUNE'])
if self.heater_bed is not None:
@ -62,10 +62,6 @@ class GCodeParser:
for h, f in self.gcode_handlers.items():
aliases = getattr(self, 'cmd_'+h+'_aliases', [])
self.gcode_handlers.update(dict([(a, f) for a in aliases]))
def finish(self):
self.reactor.end()
self.toolhead.motor_off()
logging.debug('Completed translation by klippy')
def stats(self, eventtime):
return "gcodein=%d" % (self.bytes_read,)
def set_printer_ready(self, is_ready):
@ -75,7 +71,7 @@ class GCodeParser:
self.build_handlers()
if is_ready and self.is_fileinput and self.fd_handle is None:
self.fd_handle = self.reactor.register_fd(self.fd, self.process_data)
def note_mcu_error(self):
def motor_heater_off(self):
if self.toolhead is not None:
self.toolhead.motor_off()
if self.heater_nozzle is not None:
@ -140,7 +136,8 @@ class GCodeParser:
self.input_commands = lines
self.process_commands(eventtime)
if not data and self.is_fileinput:
self.finish()
self.motor_heater_off()
self.printer.request_exit_eof()
# Response handling
def ack(self, msg=None):
if not self.need_ack or self.is_fileinput:
@ -370,6 +367,11 @@ class GCodeParser:
temp = float(params.get('S', '60'))
heater.start_auto_tune(temp)
self.bg_temp(heater)
cmd_RESTART_when_not_ready = True
cmd_RESTART_help = "Reload config file and restart host software"
def cmd_RESTART(self, params):
self.printer.request_restart()
cmd_HELP_when_not_ready = True
def cmd_HELP(self, params):
cmdhelp = ["// Available extended commands:"]
for cmd in self.gcode_handlers:

View File

@ -14,9 +14,8 @@ Printer is not ready
"""
message_restart = """
This is an unrecoverable error. Please correct the
underlying issue and then manually restart the klippy host
software.
Once the underlying issue is corrected, use the "RESTART"
command to reload the config and restart the host software.
Printer is halted
"""
@ -85,6 +84,7 @@ class Printer:
self.need_dump_debug = False
self.state_message = message_startup
self.debugoutput = self.dictionary = None
self.run_result = None
self.fileconfig = None
self.mcu = None
self.objects = {}
@ -172,10 +172,7 @@ class Printer:
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())
return self.run_result
def get_state_message(self):
return self.state_message
def note_shutdown(self, msg):
@ -187,7 +184,17 @@ class Printer:
def note_mcu_error(self, msg):
self.state_message = "%s%s" % (msg, message_restart)
self.gcode.set_printer_ready(False)
self.gcode.note_mcu_error()
self.gcode.motor_heater_off()
def disconnect(self):
if self.mcu is not None:
self.stats(time.time())
self.mcu.disconnect()
def request_restart(self):
self.run_result = "restart"
self.reactor.end()
def request_exit_eof(self):
self.run_result = "exit_eof"
self.reactor.end()
######################################################################
@ -239,11 +246,21 @@ def main():
logging.info("Starting Klippy...")
# Start firmware
printer = Printer(conffile, input_fd, is_fileinput=debuginput is not None)
if debugoutput:
proto_dict = read_dictionary(options.read_dictionary)
printer.set_fileoutput(debugoutput, proto_dict)
printer.run()
while 1:
is_fileinput = debuginput is not None
printer = Printer(conffile, input_fd, is_fileinput)
if debugoutput:
proto_dict = read_dictionary(options.read_dictionary)
printer.set_fileoutput(debugoutput, proto_dict)
res = printer.run()
if res == 'restart':
printer.disconnect()
time.sleep(1.)
logging.info("Restarting printer")
continue
elif res == 'eof_stats':
printer.disconnect()
break
if bglogger is not None:
bglogger.stop()