Refactoring Pronsole to wrap print in a self.log method so that it can be reused and overriden by a web interface or any other non-conosole interface

master
D1plo1d 2013-04-10 09:05:08 -04:00
parent e1660bd7f0
commit eb0f808bf4
1 changed files with 184 additions and 180 deletions

View File

@ -77,7 +77,7 @@ def estimate_duration(g):
#TODO: #TODO:
# get device caps from firmware: max speed, acceleration/axis (including extruder) # get device caps from firmware: max speed, acceleration/axis (including extruder)
# calculate the maximum move duration accounting for above ;) # calculate the maximum move duration accounting for above ;)
# print ".... estimating ...." # self.log(".... estimating ....")
for i in g: for i in g:
i = i.split(";")[0] i = i.split(";")[0]
if "G4" in i or "G1" in i: if "G4" in i or "G1" in i:
@ -119,7 +119,7 @@ def estimate_duration(g):
if z > lastz: if z > lastz:
layercount +=1 layercount +=1
#print "layer z: ", lastz, " will take: ", time.strftime('%H:%M:%S', time.gmtime(totalduration-layerbeginduration)) #self.log("layer z: ", lastz, " will take: ", time.strftime('%H:%M:%S', time.gmtime(totalduration-layerbeginduration)))
layerbeginduration = totalduration layerbeginduration = totalduration
lastx = x lastx = x
@ -128,7 +128,7 @@ def estimate_duration(g):
laste = e laste = e
lastf = f lastf = f
#print "Total Duration: " #, time.strftime('%H:%M:%S', time.gmtime(totalduration)) #self.log("Total Duration: " #, time.strftime('%H:%M:%S', time.gmtime(totalduration)))
return "{0:d} layers, ".format(int(layercount)) + str(datetime.timedelta(seconds = int(totalduration))) return "{0:d} layers, ".format(int(layercount)) + str(datetime.timedelta(seconds = int(totalduration)))
class Settings: class Settings:
@ -228,15 +228,18 @@ class pronsole(cmd.Cmd):
self.helpdict["final_command"] = _("Executable to run when the print is finished") self.helpdict["final_command"] = _("Executable to run when the print is finished")
self.commandprefixes='MGT$' self.commandprefixes='MGT$'
def log(self, *msg):
print ''.join(str(i) for i in msg)
def set_temp_preset(self, key, value): def set_temp_preset(self, key, value):
if not key.startswith("bed"): if not key.startswith("bed"):
self.temps["pla"] = str(self.settings.temperature_pla) self.temps["pla"] = str(self.settings.temperature_pla)
self.temps["abs"] = str(self.settings.temperature_abs) self.temps["abs"] = str(self.settings.temperature_abs)
print "Hotend temperature presets updated, pla:%s, abs:%s" % (self.temps["pla"], self.temps["abs"]) self.log("Hotend temperature presets updated, pla:%s, abs:%s" % (self.temps["pla"], self.temps["abs"]))
else: else:
self.bedtemps["pla"] = str(self.settings.bedtemp_pla) self.bedtemps["pla"] = str(self.settings.bedtemp_pla)
self.bedtemps["abs"] = str(self.settings.bedtemp_abs) self.bedtemps["abs"] = str(self.settings.bedtemp_abs)
print "Bed temperature presets updated, pla:%s, abs:%s" % (self.bedtemps["pla"], self.bedtemps["abs"]) self.log("Bed temperature presets updated, pla:%s, abs:%s" % (self.bedtemps["pla"], self.bedtemps["abs"]))
def scanserial(self): def scanserial(self):
"""scan for available ports. return a list of device names.""" """scan for available ports. return a list of device names."""
@ -254,7 +257,7 @@ class pronsole(cmd.Cmd):
return baselist+glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') +glob.glob("/dev/tty.*")+glob.glob("/dev/cu.*")+glob.glob("/dev/rfcomm*") return baselist+glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') +glob.glob("/dev/tty.*")+glob.glob("/dev/cu.*")+glob.glob("/dev/rfcomm*")
def online(self): def online(self):
print "Printer is now online" self.log("printer is now online")
sys.stdout.write(self.prompt) sys.stdout.write(self.prompt)
sys.stdout.flush() sys.stdout.flush()
@ -265,7 +268,7 @@ class pronsole(cmd.Cmd):
self.help_gcodes() self.help_gcodes()
def help_gcodes(self): def help_gcodes(self):
print "Gcodes are passed through to the printer as they are" self.log("Gcodes are passed through to the printer as they are")
def complete_macro(self, text, line, begidx, endidx): def complete_macro(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "): if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
@ -294,7 +297,7 @@ class pronsole(cmd.Cmd):
setattr(self.__class__, "do_"+self.cur_macro_name, lambda self, largs, macro = macro:macro(self,*largs.split())) setattr(self.__class__, "do_"+self.cur_macro_name, lambda self, largs, macro = macro:macro(self,*largs.split()))
setattr(self.__class__, "help_"+self.cur_macro_name, lambda self, macro_name = self.cur_macro_name: self.subhelp_macro(macro_name)) setattr(self.__class__, "help_"+self.cur_macro_name, lambda self, macro_name = self.cur_macro_name: self.subhelp_macro(macro_name))
if not self.processing_rc: if not self.processing_rc:
print "Macro '"+self.cur_macro_name+"' defined" self.log("Macro '"+self.cur_macro_name+"' defined")
# save it # save it
if not self.processing_args: if not self.processing_args:
macro_key = "macro "+self.cur_macro_name macro_key = "macro "+self.cur_macro_name
@ -306,7 +309,7 @@ class pronsole(cmd.Cmd):
macro_def += self.cur_macro_def macro_def += self.cur_macro_def
self.save_in_rc(macro_key, macro_def) self.save_in_rc(macro_key, macro_def)
else: else:
print "Empty macro - cancelled" self.log("Empty macro - cancelled")
del self.cur_macro_name, self.cur_macro_def del self.cur_macro_name, self.cur_macro_def
def compile_macro_line(self, line): def compile_macro_line(self, line):
@ -321,7 +324,7 @@ class pronsole(cmd.Cmd):
def compile_macro(self, macro_name, macro_def): def compile_macro(self, macro_name, macro_def):
if macro_def.strip() == "": if macro_def.strip() == "":
print "Empty macro - cancelled" self.log("Empty macro - cancelled")
return return
pycode = "def macro(self,*arg):\n" pycode = "def macro(self,*arg):\n"
if "\n" not in macro_def.strip(): if "\n" not in macro_def.strip():
@ -335,7 +338,7 @@ class pronsole(cmd.Cmd):
def start_macro(self, macro_name, prev_definition = "", suppress_instructions = False): def start_macro(self, macro_name, prev_definition = "", suppress_instructions = False):
if not self.processing_rc and not suppress_instructions: if not self.processing_rc and not suppress_instructions:
print "Enter macro using indented lines, end with empty line" self.log("Enter macro using indented lines, end with empty line")
self.cur_macro_name = macro_name self.cur_macro_name = macro_name
self.cur_macro_def = "" self.cur_macro_def = ""
self.onecmd = self.hook_macro # override onecmd temporarily self.onecmd = self.hook_macro # override onecmd temporarily
@ -345,11 +348,11 @@ class pronsole(cmd.Cmd):
if macro_name in self.macros.keys(): if macro_name in self.macros.keys():
delattr(self.__class__, "do_"+macro_name) delattr(self.__class__, "do_"+macro_name)
del self.macros[macro_name] del self.macros[macro_name]
print "Macro '"+macro_name+"' removed" self.log("Macro '"+macro_name+"' removed")
if not self.processing_rc and not self.processing_args: if not self.processing_rc and not self.processing_args:
self.save_in_rc("macro "+macro_name, "") self.save_in_rc("macro "+macro_name, "")
else: else:
print "Macro '"+macro_name+"' is not defined" self.log("Macro '"+macro_name+"' is not defined")
def do_macro(self, args): def do_macro(self, args):
if args.strip()=="": if args.strip()=="":
self.print_topics("User-defined macros", self.macros.keys(), 15, 80) self.print_topics("User-defined macros", self.macros.keys(), 15, 80)
@ -357,7 +360,7 @@ class pronsole(cmd.Cmd):
arglist = args.split(None, 1) arglist = args.split(None, 1)
macro_name = arglist[0] macro_name = arglist[0]
if macro_name not in self.macros and hasattr(self.__class__, "do_"+macro_name): if macro_name not in self.macros and hasattr(self.__class__, "do_"+macro_name):
print "Name '"+macro_name+"' is being used by built-in command" self.log("Name '"+macro_name+"' is being used by built-in command")
return return
if len(arglist) == 2: if len(arglist) == 2:
macro_def = arglist[1] macro_def = arglist[1]
@ -377,24 +380,24 @@ class pronsole(cmd.Cmd):
self.start_macro(macro_name) self.start_macro(macro_name)
def help_macro(self): def help_macro(self):
print "Define single-line macro: macro <name> <definition>" self.log("Define single-line macro: macro <name> <definition>")
print "Define multi-line macro: macro <name>" self.log("Define multi-line macro: macro <name>")
print "Enter macro definition in indented lines. Use {0} .. {N} to substitute macro arguments" self.log("Enter macro definition in indented lines. Use {0} .. {N} to substitute macro arguments")
print "Enter python code, prefixed with ! Use arg[0] .. arg[N] to substitute macro arguments" self.log("Enter python code, prefixed with ! Use arg[0] .. arg[N] to substitute macro arguments")
print "Delete macro: macro <name> /d" self.log("Delete macro: macro <name> /d")
print "Show macro definition: macro <name> /s" self.log("Show macro definition: macro <name> /s")
print "'macro' without arguments displays list of defined macros" self.log("'macro' without arguments displays list of defined macros")
def subhelp_macro(self, macro_name): def subhelp_macro(self, macro_name):
if macro_name in self.macros.keys(): if macro_name in self.macros.keys():
macro_def = self.macros[macro_name] macro_def = self.macros[macro_name]
if "\n" in macro_def: if "\n" in macro_def:
print "Macro '"+macro_name+"' defined as:" self.log("Macro '"+macro_name+"' defined as:")
print self.macros[macro_name]+"----------------" self.log(self.macros[macro_name]+"----------------")
else: else:
print "Macro '"+macro_name+"' defined as: '"+macro_def+"'" self.log("Macro '"+macro_name+"' defined as: '"+macro_def+"'")
else: else:
print "Macro '"+macro_name+"' is not defined" self.log("Macro '"+macro_name+"' is not defined")
def set(self, var, str): def set(self, var, str):
try: try:
@ -403,29 +406,29 @@ class pronsole(cmd.Cmd):
if not self.processing_rc and not self.processing_args: if not self.processing_rc and not self.processing_args:
self.save_in_rc("set "+var, "set %s %s" % (var, value)) self.save_in_rc("set "+var, "set %s %s" % (var, value))
except AttributeError: except AttributeError:
print "Unknown variable '%s'" % var self.log("Unknown variable '%s'" % var)
except ValueError, ve: except ValueError, ve:
print "Bad value for variable '%s', expecting %s (%s)" % (var, repr(t)[1:-1], ve.args[0]) self.log("Bad value for variable '%s', expecting %s (%s)" % (var, repr(t)[1:-1], ve.args[0]))
def do_set(self, argl): def do_set(self, argl):
args = argl.split(None, 1) args = argl.split(None, 1)
if len(args) < 1: if len(args) < 1:
for k in [kk for kk in dir(self.settings) if not kk.startswith("_")]: for k in [kk for kk in dir(self.settings) if not kk.startswith("_")]:
print "%s = %s" % (k, str(getattr(self.settings, k))) self.log("%s = %s" % (k, str(getattr(self.settings, k))))
return return
value = getattr(self.settings, args[0]) value = getattr(self.settings, args[0])
if len(args) < 2: if len(args) < 2:
try: try:
print "%s = %s" % (args[0], getattr(self.settings, args[0])) self.log("%s = %s" % (args[0], getattr(self.settings, args[0])))
except AttributeError: except AttributeError:
print "Unknown variable '%s'" % args[0] self.log("Unknown variable '%s'" % args[0])
return return
self.set(args[0], args[1]) self.set(args[0], args[1])
def help_set(self): def help_set(self):
print "Set variable: set <variable> <value>" self.log("Set variable: set <variable> <value>")
print "Show variable: set <variable>" self.log("Show variable: set <variable>")
print "'set' without arguments displays all variables" self.log("'set' without arguments displays all variables")
def complete_set(self, text, line, begidx, endidx): def complete_set(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "): if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
@ -507,16 +510,16 @@ class pronsole(cmd.Cmd):
rci.close() rci.close()
rco.close() rco.close()
#if definition != "": #if definition != "":
# print "Saved '"+key+"' to '"+self.rc_filename+"'" # self.log("Saved '"+key+"' to '"+self.rc_filename+"'")
#else: #else:
# print "Removed '"+key+"' from '"+self.rc_filename+"'" # self.log("Removed '"+key+"' from '"+self.rc_filename+"'")
except Exception, e: except Exception, e:
print "Saving failed for", key+":", str(e) self.log("Saving failed for", key+":", str(e))
finally: finally:
del rci, rco del rci, rco
def preloop(self): def preloop(self):
print "Welcome to the printer console! Type \"help\" for a list of available commands." self.log("Welcome to the printer console! Type \"help\" for a list of available commands.")
cmd.Cmd.preloop(self) cmd.Cmd.preloop(self)
def do_connect(self, l): def do_connect(self, l):
@ -532,12 +535,12 @@ class pronsole(cmd.Cmd):
try: try:
baud = int(a[1]) baud = int(a[1])
except: except:
print "Bad baud value '"+a[1]+"' ignored" self.log("Bad baud value '"+a[1]+"' ignored")
if len(p) == 0 and not port: if len(p) == 0 and not port:
print "No serial ports detected - please specify a port" self.log("No serial ports detected - please specify a port")
return return
if len(a) == 0: if len(a) == 0:
print "No port specified - connecting to %s at %dbps" % (port, baud) self.log("No port specified - connecting to %s at %dbps" % (port, baud))
if port != self.settings.port: if port != self.settings.port:
self.settings.port = port self.settings.port = port
self.save_in_rc("set port", "set port %s" % port) self.save_in_rc("set port", "set port %s" % port)
@ -547,14 +550,14 @@ class pronsole(cmd.Cmd):
self.p.connect(port, baud) self.p.connect(port, baud)
def help_connect(self): def help_connect(self):
print "Connect to printer" self.log("Connect to printer")
print "connect <port> <baudrate>" self.log("connect <port> <baudrate>")
print "If port and baudrate are not specified, connects to first detected port at 115200bps" self.log("If port and baudrate are not specified, connects to first detected port at 115200bps")
ports = self.scanserial() ports = self.scanserial()
if(len(ports)): if(len(ports)):
print "Available ports: ", " ".join(ports) self.log("Available ports: ", " ".join(ports))
else: else:
print "No serial ports were automatically found." self.log("No serial ports were automatically found.")
def complete_connect(self, text, line, begidx, endidx): def complete_connect(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "): if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
@ -568,22 +571,22 @@ class pronsole(cmd.Cmd):
self.p.disconnect() self.p.disconnect()
def help_disconnect(self): def help_disconnect(self):
print "Disconnects from the printer" self.log("Disconnects from the printer")
def do_load(self,l): def do_load(self,l):
self._do_load(l) self._do_load(l)
def _do_load(self,l): def _do_load(self,l):
if len(l)==0: if len(l)==0:
print "No file name given." self.log("No file name given.")
return return
print "Loading file:"+l self.log("Loading file:"+l)
if not(os.path.exists(l)): if not(os.path.exists(l)):
print "File not found!" self.log("File not found!")
return return
self.f = [i.replace("\n", "").replace("\r", "") for i in open(l)] self.f = [i.replace("\n", "").replace("\r", "") for i in open(l)]
self.filename = l self.filename = l
print "Loaded ", l, ", ", len(self.f)," lines." self.log("Loaded ", l, ", ", len(self.f)," lines.")
def complete_load(self, text, line, begidx, endidx): def complete_load(self, text, line, begidx, endidx):
s = line.split() s = line.split()
@ -596,32 +599,32 @@ class pronsole(cmd.Cmd):
return glob.glob("*/")+glob.glob("*.g*") return glob.glob("*/")+glob.glob("*.g*")
def help_load(self): def help_load(self):
print "Loads a gcode file (with tab-completion)" self.log("Loads a gcode file (with tab-completion)")
def do_upload(self, l): def do_upload(self, l):
if len(l) == 0: if len(l) == 0:
print "No file name given." self.log("No file name given.")
return return
print "Loading file:"+l.split()[0] self.log("Loading file:"+l.split()[0])
if not(os.path.exists(l.split()[0])): if not(os.path.exists(l.split()[0])):
print "File not found!" self.log("File not found!")
return return
if not self.p.online: if not self.p.online:
print "Not connected to printer." self.log("Not connected to printer.")
return return
self.f = [i.replace("\n", "") for i in open(l.split()[0])] self.f = [i.replace("\n", "") for i in open(l.split()[0])]
self.filename = l.split()[0] self.filename = l.split()[0]
print "Loaded ", l, ", ", len(self.f)," lines." self.log("Loaded ", l, ", ", len(self.f)," lines.")
tname = "" tname = ""
if len(l.split())>1: if len(l.split())>1:
tname = l.split()[1] tname = l.split()[1]
else: else:
print "please enter target name in 8.3 format." self.log("please enter target name in 8.3 format.")
return return
print "Uploading as ", tname self.log("Uploading as ", tname)
print("Uploading "+self.filename) self.log(("Uploading "+self.filename))
self.p.send_now("M28 "+tname) self.p.send_now("M28 "+tname)
print("Press Ctrl-C to interrupt upload.") self.log(("Press Ctrl-C to interrupt upload."))
self.p.startprint(self.f) self.p.startprint(self.f)
try: try:
sys.stdout.write("Progress: 00.0%") sys.stdout.write("Progress: 00.0%")
@ -639,16 +642,16 @@ class pronsole(cmd.Cmd):
self.recvlisteners+=[self.listfiles] self.recvlisteners+=[self.listfiles]
self.p.send_now("M20") self.p.send_now("M20")
time.sleep(0.5) time.sleep(0.5)
print "\b\b\b\b\b100%. Upload completed. ", tname, " should now be on the card." self.log("\b\b\b\b\b100%. Upload completed. ", tname, " should now be on the card.")
return return
except: except:
print "...interrupted!" self.log("...interrupted!")
self.p.pause() self.p.pause()
self.p.send_now("M29 "+tname) self.p.send_now("M29 "+tname)
time.sleep(0.2) time.sleep(0.2)
self.p.clear = 1 self.p.clear = 1
self.p.startprint([]) self.p.startprint([])
print "A partial file named ", tname, " may have been written to the sd card." self.log("A partial file named ", tname, " may have been written to the sd card.")
def complete_upload(self, text, line, begidx, endidx): def complete_upload(self, text, line, begidx, endidx):
@ -662,23 +665,23 @@ class pronsole(cmd.Cmd):
return glob.glob("*/")+glob.glob("*.g*") return glob.glob("*/")+glob.glob("*.g*")
def help_upload(self): def help_upload(self):
print "Uploads a gcode file to the sd card" self.log("Uploads a gcode file to the sd card")
def help_print(self): def help_print(self):
if self.f is None: if self.f is None:
print "Send a loaded gcode file to the printer. Load a file with the load command first." self.log("Send a loaded gcode file to the printer. Load a file with the load command first.")
else: else:
print "Send a loaded gcode file to the printer. You have "+self.filename+" loaded right now." self.log("Send a loaded gcode file to the printer. You have "+self.filename+" loaded right now.")
def do_print(self, l): def do_print(self, l):
if self.f is None: if self.f is None:
print "No file loaded. Please use load first." self.log("No file loaded. Please use load first.")
return return
if not self.p.online: if not self.p.online:
print "Not connected to printer." self.log("Not connected to printer.")
return return
print("Printing "+self.filename) self.log(("printing "+self.filename))
print("You can monitor the print with the monitor command.") self.log(("You can monitor the print with the monitor command."))
self.p.startprint(self.f) self.p.startprint(self.f)
#self.p.pause() #self.p.pause()
#self.paused = True #self.paused = True
@ -689,7 +692,7 @@ class pronsole(cmd.Cmd):
self.p.send_now("M25") self.p.send_now("M25")
else: else:
if(not self.p.printing): if(not self.p.printing):
print "Not printing, cannot pause." self.log("Not self.log(ing, cannot pause.")
return return
self.p.pause() self.p.pause()
#self.p.connect()# This seems to work, but is not a good solution. #self.p.connect()# This seems to work, but is not a good solution.
@ -698,11 +701,11 @@ class pronsole(cmd.Cmd):
#self.do_resume(None) #self.do_resume(None)
def help_pause(self): def help_pause(self):
print "Pauses a running print" self.log("Pauses a running print")
def do_resume(self, l): def do_resume(self, l):
if not self.paused: if not self.paused:
print "Not paused, unable to resume. Start a print first." self.log("Not paused, unable to resume. Start a print first.")
return return
self.paused = False self.paused = False
if self.sdprinting: if self.sdprinting:
@ -712,7 +715,7 @@ class pronsole(cmd.Cmd):
self.p.resume() self.p.resume()
def help_resume(self): def help_resume(self):
print "Resumes a paused print." self.log("Resumes a paused print.")
def emptyline(self): def emptyline(self):
pass pass
@ -731,33 +734,33 @@ class pronsole(cmd.Cmd):
def do_ls(self, l): def do_ls(self, l):
if not self.p.online: if not self.p.online:
print "Printer is not online. Try connect to it first." self.log("printer is not online. Try connect to it first.")
return return
self.listing = 2 self.listing = 2
self.sdfiles = [] self.sdfiles = []
self.recvlisteners+=[self.listfiles] self.recvlisteners+=[self.listfiles]
self.p.send_now("M20") self.p.send_now("M20")
time.sleep(0.5) time.sleep(0.5)
print " ".join(self.sdfiles) self.log(" ".join(self.sdfiles))
def help_ls(self): def help_ls(self):
print "lists files on the SD card" self.log("lists files on the SD card")
def waitforsdresponse(self, l): def waitforsdresponse(self, l):
if "file.open failed" in l: if "file.open failed" in l:
print "Opening file failed." self.log("Opening file failed.")
self.recvlisteners.remove(self.waitforsdresponse) self.recvlisteners.remove(self.waitforsdresponse)
return return
if "File opened" in l: if "File opened" in l:
print l self.log(l)
if "File selected" in l: if "File selected" in l:
print "Starting print" self.log("Starting print")
self.p.send_now("M24") self.p.send_now("M24")
self.sdprinting = 1 self.sdprinting = 1
#self.recvlisteners.remove(self.waitforsdresponse) #self.recvlisteners.remove(self.waitforsdresponse)
return return
if "Done printing file" in l: if "Done printing file" in l:
print l self.log(l)
self.sdprinting = 0 self.sdprinting = 0
self.recvlisteners.remove(self.waitforsdresponse) self.recvlisteners.remove(self.waitforsdresponse)
return return
@ -774,11 +777,11 @@ class pronsole(cmd.Cmd):
self.p.reset() self.p.reset()
def help_reset(self): def help_reset(self):
print "Resets the printer." self.log("Resets the printer.")
def do_sdprint(self, l): def do_sdprint(self, l):
if not self.p.online: if not self.p.online:
print "Printer is not online. Try connect to it first." self.log("printer is not online. Try connect to it first.")
return return
self.listing = 2 self.listing = 2
self.sdfiles = [] self.sdfiles = []
@ -786,17 +789,17 @@ class pronsole(cmd.Cmd):
self.p.send_now("M20") self.p.send_now("M20")
time.sleep(0.5) time.sleep(0.5)
if not (l.lower() in self.sdfiles): if not (l.lower() in self.sdfiles):
print "File is not present on card. Upload it first" self.log("File is not present on card. Upload it first")
return return
self.recvlisteners+=[self.waitforsdresponse] self.recvlisteners+=[self.waitforsdresponse]
self.p.send_now("M23 "+l.lower()) self.p.send_now("M23 "+l.lower())
print "Printing file: "+l.lower()+" from SD card." self.log("printing file: "+l.lower()+" from SD card.")
print "Requesting SD print..." self.log("Requesting SD print...")
time.sleep(1) time.sleep(1)
def help_sdprint(self): def help_sdprint(self):
print "Print a file from the SD card. Tabcompletes with available file names." self.log("print a file from the SD card. Tabcompletes with available file names.")
print "sdprint filename.g" self.log("sdprint filename.g")
def complete_sdprint(self, text, line, begidx, endidx): def complete_sdprint(self, text, line, begidx, endidx):
if self.sdfiles==[] and self.p.online: if self.sdfiles==[] and self.p.online:
@ -810,34 +813,35 @@ class pronsole(cmd.Cmd):
def recvcb(self, l): def recvcb(self, l):
if "T:" in l: if "T:" in l:
self.tempreadings = l self.tempreadings = l
tstring = l.rstrip() tstring = l.rstrip()
if(tstring!="ok" and not tstring.startswith("ok T") and not tstring.startswith("T:") and not self.listing and not self.monitoring): if(tstring!="ok" and not tstring.startswith("ok T") and not tstring.startswith("T:") and not self.listing and not self.monitoring):
print tstring self.log(tstring)
sys.stdout.write(self.prompt) sys.stdout.write(self.prompt)
sys.stdout.flush() sys.stdout.flush()
for i in self.recvlisteners: for i in self.recvlisteners:
i(l) i(l)
def help_shell(self): def help_shell(self):
print "Executes a python command. Example:" self.log("Executes a python command. Example:")
print "! os.listdir('.')" self.log("! os.listdir('.')")
def default(self, l): def default(self, l):
if(l[0] in self.commandprefixes.upper()): if(l[0] in self.commandprefixes.upper()):
if(self.p and self.p.online): if(self.p and self.p.online):
if(not self.p.loud): if(not self.p.loud):
print "SENDING:"+l self.log("SENDING:"+l)
self.p.send_now(l) self.p.send_now(l)
else: else:
print "Printer is not online." self.log("printer is not online.")
return return
elif(l[0] in self.commandprefixes.lower()): elif(l[0] in self.commandprefixes.lower()):
if(self.p and self.p.online): if(self.p and self.p.online):
if(not self.p.loud): if(not self.p.loud):
print "SENDING:"+l.upper() self.log("SENDING:"+l.upper())
self.p.send_now(l.upper()) self.p.send_now(l.upper())
else: else:
print "Printer is not online." self.log("printer is not online.")
return return
else: else:
cmd.Cmd.default(self, l) cmd.Cmd.default(self, l)
@ -847,7 +851,7 @@ class pronsole(cmd.Cmd):
def tempcb(self, l): def tempcb(self, l):
if "T:" in l: if "T:" in l:
print l.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", "") self.log(l.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", ""))
def do_gettemp(self, l): def do_gettemp(self, l):
if self.p.online: if self.p.online:
@ -857,7 +861,7 @@ class pronsole(cmd.Cmd):
self.recvlisteners.remove(self.tempcb) self.recvlisteners.remove(self.tempcb)
def help_gettemp(self): def help_gettemp(self):
print "Read the extruder and bed temperature." self.log("Read the extruder and bed temperature.")
def do_settemp(self, l): def do_settemp(self, l):
try: try:
@ -868,18 +872,18 @@ class pronsole(cmd.Cmd):
if f>=0: if f>=0:
if self.p.online: if self.p.online:
self.p.send_now("M104 S"+l) self.p.send_now("M104 S"+l)
print "Setting hotend temperature to ", f, " degrees Celsius." self.log("Setting hotend temperature to ", f, " degrees Celsius.")
else: else:
print "Printer is not online." self.log("printer is not online.")
else: else:
print "You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0." self.log("You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0.")
except: except:
print "You must enter a temperature." self.log("You must enter a temperature.")
def help_settemp(self): def help_settemp(self):
print "Sets the hotend temperature to the value entered." self.log("Sets the hotend temperature to the value entered.")
print "Enter either a temperature in celsius or one of the following keywords" self.log("Enter either a temperature in celsius or one of the following keywords")
print ", ".join([i+"("+self.temps[i]+")" for i in self.temps.keys()]) self.log(", ".join([i+"("+self.temps[i]+")" for i in self.temps.keys()]))
def complete_settemp(self, text, line, begidx, endidx): def complete_settemp(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "): if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
@ -894,18 +898,18 @@ class pronsole(cmd.Cmd):
if f>=0: if f>=0:
if self.p.online: if self.p.online:
self.p.send_now("M140 S"+l) self.p.send_now("M140 S"+l)
print "Setting bed temperature to ", f, " degrees Celsius." self.log("Setting bed temperature to ", f, " degrees Celsius.")
else: else:
print "Printer is not online." self.log("printer is not online.")
else: else:
print "You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0." self.log("You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0.")
except: except:
print "You must enter a temperature." self.log("You must enter a temperature.")
def help_bedtemp(self): def help_bedtemp(self):
print "Sets the bed temperature to the value entered." self.log("Sets the bed temperature to the value entered.")
print "Enter either a temperature in celsius or one of the following keywords" self.log("Enter either a temperature in celsius or one of the following keywords")
print ", ".join([i+"("+self.bedtemps[i]+")" for i in self.bedtemps.keys()]) self.log(", ".join([i+"("+self.bedtemps[i]+")" for i in self.bedtemps.keys()]))
def complete_bedtemp(self, text, line, begidx, endidx): def complete_bedtemp(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "): if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
@ -913,13 +917,13 @@ class pronsole(cmd.Cmd):
def do_move(self, l): def do_move(self, l):
if(len(l.split())<2): if(len(l.split())<2):
print "No move specified." self.log("No move specified.")
return return
if self.p.printing: if self.p.printing:
print "Printer is currently printing. Please pause the print before you issue manual commands." self.log("printer is currently printing. Please pause the print before you issue manual commands.")
return return
if not self.p.online: if not self.p.online:
print "Printer is not online. Unable to move." self.log("printer is not online. Unable to move.")
return return
l = l.split() l = l.split()
if(l[0].lower()=="x"): if(l[0].lower()=="x"):
@ -935,13 +939,13 @@ class pronsole(cmd.Cmd):
feed = self.settings.e_feedrate feed = self.settings.e_feedrate
axis = "E" axis = "E"
else: else:
print "Unknown axis." self.log("Unknown axis.")
return return
dist = 0 dist = 0
try: try:
dist = float(l[1]) dist = float(l[1])
except: except:
print "Invalid distance" self.log("Invalid distance")
return return
try: try:
feed = int(l[2]) feed = int(l[2])
@ -952,11 +956,11 @@ class pronsole(cmd.Cmd):
self.p.send_now("G90") self.p.send_now("G90")
def help_move(self): def help_move(self):
print "Move an axis. Specify the name of the axis and the amount. " self.log("Move an axis. Specify the name of the axis and the amount. ")
print "move X 10 will move the X axis forward by 10mm at ", self.settings.xy_feedrate, "mm/min (default XY speed)" self.log("move X 10 will move the X axis forward by 10mm at ", self.settings.xy_feedrate, "mm/min (default XY speed)")
print "move Y 10 5000 will move the Y axis forward by 10mm at 5000mm/min" self.log("move Y 10 5000 will move the Y axis forward by 10mm at 5000mm/min")
print "move Z -1 will move the Z axis down by 1mm at ", self.settings.z_feedrate, "mm/min (default Z speed)" self.log("move Z -1 will move the Z axis down by 1mm at ", self.settings.z_feedrate, "mm/min (default Z speed)")
print "Common amounts are in the tabcomplete list." self.log("Common amounts are in the tabcomplete list.")
def complete_move(self, text, line, begidx, endidx): def complete_move(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "): if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
@ -976,29 +980,29 @@ class pronsole(cmd.Cmd):
length = 5#default extrusion length length = 5#default extrusion length
feed = self.settings.e_feedrate#default speed feed = self.settings.e_feedrate#default speed
if not self.p.online: if not self.p.online:
print "Printer is not online. Unable to move." self.log("printer is not online. Unable to move.")
return return
if self.p.printing: if self.p.printing:
print "Printer is currently printing. Please pause the print before you issue manual commands." self.log("printer is currently printing. Please pause the print before you issue manual commands.")
return return
ls = l.split() ls = l.split()
if len(ls): if len(ls):
try: try:
length = float(ls[0]) length = float(ls[0])
except: except:
print "Invalid length given." self.log("Invalid length given.")
if len(ls)>1: if len(ls)>1:
try: try:
feed = int(ls[1]) feed = int(ls[1])
except: except:
print "Invalid speed given." self.log("Invalid speed given.")
if override is not None: if override is not None:
length = override length = override
feed = overridefeed feed = overridefeed
if length > 0: if length > 0:
print "Extruding %fmm of filament."%(length,) self.log("Extruding %fmm of filament."%(length,))
elif length <0: elif length <0:
print "Reversing %fmm of filament."%(-1*length,) self.log("Reversing %fmm of filament."%(-1*length,))
else: else:
"Length is 0, not doing anything." "Length is 0, not doing anything."
self.p.send_now("G91") self.p.send_now("G91")
@ -1006,62 +1010,62 @@ class pronsole(cmd.Cmd):
self.p.send_now("G90") self.p.send_now("G90")
def help_extrude(self): def help_extrude(self):
print "Extrudes a length of filament, 5mm by default, or the number of mm given as a parameter" self.log("Extrudes a length of filament, 5mm by default, or the number of mm given as a parameter")
print "extrude - extrudes 5mm of filament at 300mm/min (5mm/s)" self.log("extrude - extrudes 5mm of filament at 300mm/min (5mm/s)")
print "extrude 20 - extrudes 20mm of filament at 300mm/min (5mm/s)" self.log("extrude 20 - extrudes 20mm of filament at 300mm/min (5mm/s)")
print "extrude -5 - REVERSES 5mm of filament at 300mm/min (5mm/s)" self.log("extrude -5 - REVERSES 5mm of filament at 300mm/min (5mm/s)")
print "extrude 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)" self.log("extrude 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)")
def do_reverse(self, l): def do_reverse(self, l):
length = 5#default extrusion length length = 5#default extrusion length
feed = self.settings.e_feedrate#default speed feed = self.settings.e_feedrate#default speed
if not self.p.online: if not self.p.online:
print "Printer is not online. Unable to move." self.log("printer is not online. Unable to move.")
return return
if self.p.printing: if self.p.printing:
print "Printer is currently printing. Please pause the print before you issue manual commands." self.log("printer is currently printing. Please pause the print before you issue manual commands.")
return return
ls = l.split() ls = l.split()
if len(ls): if len(ls):
try: try:
length = float(ls[0]) length = float(ls[0])
except: except:
print "Invalid length given." self.log("Invalid length given.")
if len(ls)>1: if len(ls)>1:
try: try:
feed = int(ls[1]) feed = int(ls[1])
except: except:
print "Invalid speed given." self.log("Invalid speed given.")
self.do_extrude("", length*-1.0, feed) self.do_extrude("", length*-1.0, feed)
def help_reverse(self): def help_reverse(self):
print "Reverses the extruder, 5mm by default, or the number of mm given as a parameter" self.log("Reverses the extruder, 5mm by default, or the number of mm given as a parameter")
print "reverse - reverses 5mm of filament at 300mm/min (5mm/s)" self.log("reverse - reverses 5mm of filament at 300mm/min (5mm/s)")
print "reverse 20 - reverses 20mm of filament at 300mm/min (5mm/s)" self.log("reverse 20 - reverses 20mm of filament at 300mm/min (5mm/s)")
print "reverse 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)" self.log("reverse 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)")
print "reverse -5 - EXTRUDES 5mm of filament at 300mm/min (5mm/s)" self.log("reverse -5 - EXTRUDES 5mm of filament at 300mm/min (5mm/s)")
def do_exit(self, l): def do_exit(self, l):
print "Disconnecting from printer..." self.log("Disconnecting from printer...")
self.p.disconnect() self.p.disconnect()
print "Exiting program. Goodbye!" self.log("Exiting program. Goodbye!")
return True return True
def help_exit(self): def help_exit(self):
print "Disconnects from the printer and exits the program." self.log("Disconnects from the printer and exits the program.")
def do_monitor(self, l): def do_monitor(self, l):
interval = 5 interval = 5
if not self.p.online: if not self.p.online:
print "Printer is not online. Please connect first." self.log("printer is not online. Please connect first.")
return return
print "Monitoring printer, use ^C to interrupt." self.log("Monitoring printer, use ^C to interrupt.")
if len(l): if len(l):
try: try:
interval = float(l) interval = float(l)
except: except:
print "Invalid period given." self.log("Invalid period given.")
print "Updating values every %f seconds."%(interval,) self.log("Updating values every %f seconds."%(interval,))
self.monitoring = 1 self.monitoring = 1
try: try:
while(1): while(1):
@ -1069,22 +1073,22 @@ class pronsole(cmd.Cmd):
if(self.sdprinting): if(self.sdprinting):
self.p.send_now("M27") self.p.send_now("M27")
time.sleep(interval) time.sleep(interval)
#print (self.tempreadings.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", "")) #self.log((self.tempreadings.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", "")))
if(self.p.printing): if(self.p.printing):
print "Print progress: ", 100*float(self.p.queueindex)/len(self.p.mainqueue), "%" self.log("print progress: ", 100*float(self.p.queueindex)/len(self.p.mainqueue), "%")
if(self.sdprinting): if(self.sdprinting):
print "SD print progress: ", self.percentdone, "%" self.log("SD print progress: ", self.percentdone, "%")
except: except:
print "Done monitoring." self.log("Done monitoring.")
pass pass
self.monitoring = 0 self.monitoring = 0
def help_monitor(self): def help_monitor(self):
print "Monitor a machine's temperatures and an SD print's status." self.log("Monitor a machine's temperatures and an SD print's status.")
print "monitor - Reports temperature and SD print status (if SD printing) every 5 seconds" self.log("monitor - Reports temperature and SD print status (if SD printing) every 5 seconds")
print "monitor 2 - Reports temperature and SD print status (if SD printing) every 2 seconds" self.log("monitor 2 - Reports temperature and SD print status (if SD printing) every 2 seconds")
def expandcommand(self, c): def expandcommand(self, c):
return c.replace("$python", sys.executable) return c.replace("$python", sys.executable)
@ -1092,31 +1096,31 @@ class pronsole(cmd.Cmd):
def do_skein(self, l): def do_skein(self, l):
l = l.split() l = l.split()
if len(l) == 0: if len(l) == 0:
print "No file name given." self.log("No file name given.")
return return
settings = 0 settings = 0
if(l[0]=="set"): if(l[0]=="set"):
settings = 1 settings = 1
else: else:
print "Skeining file:"+l[0] self.log("Skeining file:"+l[0])
if not(os.path.exists(l[0])): if not(os.path.exists(l[0])):
print "File not found!" self.log("File not found!")
return return
try: try:
import shlex import shlex
if(settings): if(settings):
param = self.expandcommand(self.settings.sliceoptscommand).replace("\\", "\\\\").encode() param = self.expandcommand(self.settings.sliceoptscommand).replace("\\", "\\\\").encode()
print "Entering slicer settings: ", param self.log("Entering slicer settings: ", param)
subprocess.call(shlex.split(param)) subprocess.call(shlex.split(param))
else: else:
param = self.expandcommand(self.settings.slicecommand).encode() param = self.expandcommand(self.settings.slicecommand).encode()
print "Slicing: ", param self.log("Slicing: ", param)
params = [i.replace("$s", l[0]).replace("$o", l[0].replace(".stl", "_export.gcode").replace(".STL", "_export.gcode")).encode() for i in shlex.split(param.replace("\\", "\\\\").encode())] params = [i.replace("$s", l[0]).replace("$o", l[0].replace(".stl", "_export.gcode").replace(".STL", "_export.gcode")).encode() for i in shlex.split(param.replace("\\", "\\\\").encode())]
subprocess.call(params) subprocess.call(params)
print "Loading sliced file." self.log("Loading sliced file.")
self.do_load(l[0].replace(".stl", "_export.gcode")) self.do_load(l[0].replace(".stl", "_export.gcode"))
except Exception, e: except Exception, e:
print "Skeinforge execution failed: ", e self.log("Skeinforge execution failed: ", e)
def complete_skein(self, text, line, begidx, endidx): def complete_skein(self, text, line, begidx, endidx):
s = line.split() s = line.split()
@ -1129,18 +1133,18 @@ class pronsole(cmd.Cmd):
return glob.glob("*/")+glob.glob("*.stl") return glob.glob("*/")+glob.glob("*.stl")
def help_skein(self): def help_skein(self):
print "Creates a gcode file from an stl model using the slicer (with tab-completion)" self.log("Creates a gcode file from an stl model using the slicer (with tab-completion)")
print "skein filename.stl - create gcode file" self.log("skein filename.stl - create gcode file")
print "skein filename.stl view - create gcode file and view using skeiniso" self.log("skein filename.stl view - create gcode file and view using skeiniso")
print "skein set - adjust slicer settings" self.log("skein set - adjust slicer settings")
def do_home(self, l): def do_home(self, l):
if not self.p.online: if not self.p.online:
print "Printer is not online. Unable to move." self.log("printer is not online. Unable to move.")
return return
if self.p.printing: if self.p.printing:
print "Printer is currently printing. Please pause the print before you issue manual commands." self.log("printer is currently printing. Please pause the print before you issue manual commands.")
return return
if "x" in l.lower(): if "x" in l.lower():
self.p.send_now("G28 X0") self.p.send_now("G28 X0")
@ -1155,26 +1159,26 @@ class pronsole(cmd.Cmd):
self.p.send_now("G92 E0") self.p.send_now("G92 E0")
def help_home(self): def help_home(self):
print "Homes the printer" self.log("Homes the printer")
print "home - homes all axes and zeroes the extruder(Using G28 and G92)" self.log("home - homes all axes and zeroes the extruder(Using G28 and G92)")
print "home xy - homes x and y axes (Using G28)" self.log("home xy - homes x and y axes (Using G28)")
print "home z - homes z axis only (Using G28)" self.log("home z - homes z axis only (Using G28)")
print "home e - set extruder position to zero (Using G92)" self.log("home e - set extruder position to zero (Using G92)")
print "home xyze - homes all axes and zeroes the extruder (Using G28 and G92)" self.log("home xyze - homes all axes and zeroes the extruder (Using G28 and G92)")
def parse_cmdline(self, args): def parse_cmdline(self, args):
import getopt import getopt
opts, args = getopt.getopt(args, "c:e:hw", ["conf = ", "config = ", "help"]) opts, args = getopt.getopt(args, "c:e:hw", ["conf = ", "config = ", "help"])
for o, a in opts: for o, a in opts:
#print repr((o, a)) #self.log(repr((o, a)))
if o in ("-c", "--conf", "--config"): if o in ("-c", "--conf", "--config"):
self.load_rc(a) self.load_rc(a)
elif o in ("-h", "--help"): elif o in ("-h", "--help"):
print "Usage: "+sys.argv[0]+' [-c filename [-c filename2 ... ] ] [-e "command" ...]' self.log("Usage: "+sys.argv[0]+' [-c filename [-c filename2 ... ] ] [-e "command" ...]')
print " -c | --conf | --config - override startup .pronsolerc file" self.log(" -c | --conf | --config - override startup .pronsolerc file")
print " may chain config files, settings auto-save will go into last file in the chain" self.log(" may chain config files, settings auto-save will go into last file in the chain")
print ' -e <command> - executes command after configuration/.pronsolerc is loaded' self.log(' -e <command> - executes command after configuration/.pronsolerc is loaded')
print " macros/settings from these commands are not autosaved" self.log(" macros/settings from these commands are not autosaved")
sys.exit() sys.exit()
if not self.rc_loaded: if not self.rc_loaded:
self.load_default_rc() self.load_default_rc()