2011-06-09 14:43:03 +00:00
#!/usr/bin/env python
2012-01-23 11:36:49 +00:00
# This file is part of the Printrun suite.
2012-08-08 06:39:50 +00:00
#
2012-01-23 11:36:49 +00:00
# Printrun is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
2012-08-08 06:39:50 +00:00
#
2012-01-23 11:36:49 +00:00
# Printrun is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
2012-08-08 06:39:50 +00:00
#
2012-01-23 11:36:49 +00:00
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
2012-08-08 06:39:50 +00:00
import cmd , sys
2012-08-07 11:54:07 +00:00
import glob , os , time , datetime
2012-08-08 06:39:50 +00:00
import sys , subprocess
2012-07-15 12:55:11 +00:00
import math , codecs
2011-11-04 10:49:05 +00:00
from math import sqrt
2013-05-16 10:21:37 +00:00
import argparse
2012-07-31 08:51:17 +00:00
2012-08-04 08:43:29 +00:00
import printcore
2012-07-31 08:51:17 +00:00
from printrun . printrun_utils import install_locale
install_locale ( ' pronterface ' )
2011-12-01 01:33:55 +00:00
2012-08-08 07:38:48 +00:00
if os . name == " nt " :
2011-05-30 09:09:04 +00:00
try :
import _winreg
except :
pass
2012-08-08 07:38:48 +00:00
READLINE = True
2011-05-30 09:09:04 +00:00
try :
import readline
try :
2012-08-08 07:38:48 +00:00
readline . rl . mode . show_all_if_ambiguous = " on " #config pyreadline on windows
2011-05-30 09:09:04 +00:00
except :
2011-05-30 09:53:45 +00:00
pass
except :
2012-08-08 07:38:48 +00:00
READLINE = False #neither readline module is available
2011-05-26 22:16:57 +00:00
2011-05-28 17:08:22 +00:00
def dosify ( name ) :
2011-05-31 15:08:23 +00:00
return os . path . split ( name ) [ 1 ] . split ( " . " ) [ 0 ] [ : 8 ] + " .g "
2012-08-08 06:39:50 +00:00
2013-02-03 02:24:07 +00:00
def confirm ( ) :
y_or_n = raw_input ( " y/n: " )
if y_or_n == " y " :
return True
elif y_or_n != " n " :
return confirm ( )
return False
2011-06-29 18:50:09 +00:00
class Settings :
2012-08-08 07:58:09 +00:00
#def _temperature_alias(self): return {"pla":210, "abs":230, "off":0}
2012-08-08 07:38:48 +00:00
#def _temperature_validate(self, v):
2011-06-29 18:50:09 +00:00
# if v < 0: raise ValueError("You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0.")
2012-08-08 07:58:09 +00:00
#def _bedtemperature_alias(self): return {"pla":60, "abs":110, "off":0}
2011-06-29 18:50:09 +00:00
def _baudrate_list ( self ) : return [ " 2400 " , " 9600 " , " 19200 " , " 38400 " , " 57600 " , " 115200 " ]
def __init__ ( self ) :
# defaults here.
# the initial value determines the type
self . port = " "
2011-06-29 19:23:20 +00:00
self . baudrate = 115200
2011-10-25 19:56:44 +00:00
self . bedtemp_abs = 110
2011-12-20 11:48:23 +00:00
self . bedtemp_pla = 60
self . temperature_abs = 230
self . temperature_pla = 185
2011-06-29 19:23:20 +00:00
self . xy_feedrate = 3000
self . z_feedrate = 200
self . e_feedrate = 300
2012-08-08 07:38:48 +00:00
self . slicecommand = " python skeinforge/skeinforge_application/skeinforge_utilities/skeinforge_craft.py $s "
self . sliceoptscommand = " python skeinforge/skeinforge_application/skeinforge.py "
2012-05-03 20:55:41 +00:00
self . final_command = " "
2011-12-20 11:48:23 +00:00
2012-08-08 07:38:48 +00:00
def _set ( self , key , value ) :
2011-06-29 18:50:09 +00:00
try :
2012-08-08 07:58:09 +00:00
value = getattr ( self , " _ %s _alias " % key ) ( ) [ value ]
2011-06-29 18:50:09 +00:00
except KeyError :
pass
except AttributeError :
pass
try :
2012-08-08 07:58:09 +00:00
getattr ( self , " _ %s _validate " % key ) ( value )
2011-06-29 18:50:09 +00:00
except AttributeError :
pass
2012-08-08 07:38:48 +00:00
setattr ( self , key , type ( getattr ( self , key ) ) ( value ) )
2011-06-29 18:50:09 +00:00
try :
2012-08-08 07:58:09 +00:00
getattr ( self , " _ %s _cb " % key ) ( key , value )
2011-06-29 18:50:09 +00:00
except AttributeError :
pass
return value
2012-08-08 07:38:48 +00:00
def _tabcomplete ( self , key ) :
2011-06-29 18:50:09 +00:00
try :
2012-08-08 07:58:09 +00:00
return getattr ( self , " _ %s _list " % key ) ( )
2011-06-29 18:50:09 +00:00
except AttributeError :
pass
try :
2012-08-08 07:58:09 +00:00
return getattr ( self , " _ %s _alias " % key ) ( ) . keys ( )
2011-06-29 18:50:09 +00:00
except AttributeError :
pass
return [ ]
2011-07-26 16:19:45 +00:00
def _all_settings ( self ) :
2012-08-08 07:38:48 +00:00
return dict ( [ ( k , getattr ( self , k ) ) for k in self . __dict__ . keys ( ) if not k . startswith ( " _ " ) ] )
2011-05-26 22:16:57 +00:00
2013-01-12 00:02:14 +00:00
class Status :
def __init__ ( self ) :
self . extruder_temp = 0
self . extruder_temp_target = 0
self . bed_temp = 0
self . bed_temp_target = 0
self . print_job = None
self . print_job_progress = 1.0
def update_tempreading ( self , tempstr ) :
r = tempstr . split ( )
# eg. r = ["ok", "T:20.5", "/0.0", "B:0.0", "/0.0", "@:0"]
if len ( r ) == 6 :
self . extruder_temp = float ( r [ 1 ] [ 2 : ] )
self . extruder_temp_target = float ( r [ 2 ] [ 1 : ] )
self . bed_temp = float ( r [ 3 ] [ 2 : ] )
self . bed_temp_target = float ( r [ 4 ] [ 1 : ] )
@property
def bed_enabled ( self ) :
return self . bed_temp != 0
@property
def extruder_enabled ( self ) :
return self . extruder_temp != 0
2011-05-26 22:16:57 +00:00
class pronsole ( cmd . Cmd ) :
def __init__ ( self ) :
cmd . Cmd . __init__ ( self )
2011-05-30 09:09:04 +00:00
if not READLINE :
2012-08-08 07:38:48 +00:00
self . completekey = None
2013-01-12 00:02:14 +00:00
self . status = Status ( )
2013-01-12 19:14:10 +00:00
self . dynamic_temp = False
2012-08-08 07:38:48 +00:00
self . p = printcore . printcore ( )
self . p . recvcb = self . recvcb
2012-08-08 07:58:09 +00:00
self . recvlisteners = [ ]
2013-01-09 23:59:39 +00:00
self . in_macro = False
2012-08-08 07:38:48 +00:00
self . p . onlinecb = self . online
self . f = None
self . listing = 0
2012-08-08 07:58:09 +00:00
self . sdfiles = [ ]
2012-08-08 07:38:48 +00:00
self . paused = False
self . sdprinting = 0
2012-08-08 07:58:09 +00:00
self . temps = { " pla " : " 185 " , " abs " : " 230 " , " off " : " 0 " }
self . bedtemps = { " pla " : " 60 " , " abs " : " 110 " , " off " : " 0 " }
2012-08-08 07:38:48 +00:00
self . percentdone = 0
self . tempreadings = " "
2012-08-08 07:58:09 +00:00
self . macros = { }
2012-08-08 07:38:48 +00:00
self . rc_loaded = False
self . processing_rc = False
self . processing_args = False
2011-06-29 18:50:09 +00:00
self . settings = Settings ( )
self . settings . _port_list = self . scanserial
self . settings . _temperature_abs_cb = self . set_temp_preset
self . settings . _temperature_pla_cb = self . set_temp_preset
self . settings . _bedtemp_abs_cb = self . set_temp_preset
self . settings . _bedtemp_pla_cb = self . set_temp_preset
2012-08-08 07:38:48 +00:00
self . monitoring = 0
2013-04-20 00:42:03 +00:00
self . silent = False
2011-12-20 11:48:23 +00:00
self . helpdict = { }
self . helpdict [ " baudrate " ] = _ ( " Communications Speed (default: 115200) " )
self . helpdict [ " bedtemp_abs " ] = _ ( " Heated Build Platform temp for ABS (default: 110 deg C) " )
self . helpdict [ " bedtemp_pla " ] = _ ( " Heated Build Platform temp for PLA (default: 60 deg C) " )
self . helpdict [ " e_feedrate " ] = _ ( " Feedrate for Control Panel Moves in Extrusions (default: 300mm/min) " )
self . helpdict [ " port " ] = _ ( " Port used to communicate with printer " )
2012-01-19 08:26:23 +00:00
self . helpdict [ " slicecommand " ] = _ ( " Slice command \n default: \n python skeinforge/skeinforge_application/skeinforge_utilities/skeinforge_craft.py $s) " )
self . helpdict [ " sliceoptscommand " ] = _ ( " Slice settings command \n default: \n python skeinforge/skeinforge_application/skeinforge.py " )
2011-12-20 11:48:23 +00:00
self . helpdict [ " temperature_abs " ] = _ ( " Extruder temp for ABS (default: 230 deg C) " )
self . helpdict [ " temperature_pla " ] = _ ( " Extruder temp for PLA (default: 185 deg C) " )
self . helpdict [ " xy_feedrate " ] = _ ( " Feedrate for Control Panel Moves in X and Y (default: 3000mm/min) " )
self . helpdict [ " z_feedrate " ] = _ ( " Feedrate for Control Panel Moves in Z (default: 200mm/min) " )
2012-05-03 20:55:41 +00:00
self . helpdict [ " final_command " ] = _ ( " Executable to run when the print is finished " )
2012-03-01 13:13:57 +00:00
self . commandprefixes = ' MGT$ '
2013-01-20 00:34:07 +00:00
self . promptstrs = { " offline " : " %(bold)s uninitialized> %(normal)s " ,
" fallback " : " %(bold)s PC> %(normal)s " ,
" macro " : " %(bold)s ..> %(normal)s " ,
" online " : " %(bold)s T: %(extruder_temp_fancy)s %(progress_fancy)s > %(normal)s " }
2012-08-08 06:39:50 +00:00
2013-04-10 13:05:08 +00:00
def log ( self , * msg ) :
print ' ' . join ( str ( i ) for i in msg )
2013-01-09 23:59:39 +00:00
def promptf ( self ) :
""" A function to generate prompts so that we can do dynamic prompts. """
if self . in_macro :
2013-01-20 00:34:07 +00:00
promptstr = self . promptstrs [ " macro " ]
2013-01-12 00:02:14 +00:00
elif not self . p . online :
2013-01-20 00:34:07 +00:00
promptstr = self . promptstrs [ " offline " ]
elif self . status . extruder_enabled :
promptstr = self . promptstrs [ " online " ]
else :
promptstr = self . promptstrs [ " fallback " ]
if not " % " in promptstr :
return promptstr
else :
specials = { }
specials [ " extruder_temp " ] = str ( int ( self . status . extruder_temp ) )
specials [ " extruder_temp_target " ] = str ( int ( self . status . extruder_temp_target ) )
2013-01-12 00:02:14 +00:00
if self . status . extruder_temp_target == 0 :
2013-01-20 00:34:07 +00:00
specials [ " extruder_temp_fancy " ] = str ( int ( self . status . extruder_temp ) )
2013-01-12 00:02:14 +00:00
else :
2013-01-20 00:34:07 +00:00
specials [ " extruder_temp_fancy " ] = " %s / %s " % ( str ( int ( self . status . extruder_temp ) ) , str ( int ( self . status . extruder_temp_target ) ) )
if self . p . printing :
progress = int ( 1000 * float ( self . p . queueindex ) / len ( self . p . mainqueue ) ) / 10
elif self . sdprinting :
progress = self . percentdone
else :
progress = 0.0
specials [ " progress " ] = str ( progress )
if self . p . printing or self . sdprinting :
specials [ " progress_fancy " ] = str ( progress ) + " % "
else :
specials [ " progress_fancy " ] = " ? % "
specials [ " bold " ] = " \033 [01m "
specials [ " normal " ] = " \033 [00m "
return promptstr % specials
2013-01-09 23:59:39 +00:00
def postcmd ( self , stop , line ) :
""" A hook we override to generate prompts after
2013-01-12 00:02:14 +00:00
each command is executed , for the next prompt .
We also use it to send M105 commands so that
temp info gets updated for the prompt . """
2013-01-12 19:14:10 +00:00
if self . p . online and self . dynamic_temp :
2013-01-12 00:02:14 +00:00
self . p . send_now ( " M105 " )
2013-01-09 23:59:39 +00:00
self . prompt = self . promptf ( )
return stop
2012-08-08 07:38:48 +00:00
def set_temp_preset ( self , key , value ) :
2011-06-29 18:50:09 +00:00
if not key . startswith ( " bed " ) :
self . temps [ " pla " ] = str ( self . settings . temperature_pla )
self . temps [ " abs " ] = str ( self . settings . temperature_abs )
2013-04-10 13:05:08 +00:00
self . log ( " Hotend temperature presets updated, pla: %s , abs: %s " % ( self . temps [ " pla " ] , self . temps [ " abs " ] ) )
2011-06-29 18:50:09 +00:00
else :
self . bedtemps [ " pla " ] = str ( self . settings . bedtemp_pla )
self . bedtemps [ " abs " ] = str ( self . settings . bedtemp_abs )
2013-04-10 13:05:08 +00:00
self . log ( " Bed temperature presets updated, pla: %s , abs: %s " % ( self . bedtemps [ " pla " ] , self . bedtemps [ " abs " ] ) )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def scanserial ( self ) :
""" scan for available ports. return a list of device names. """
2012-08-08 07:58:09 +00:00
baselist = [ ]
2012-08-08 07:38:48 +00:00
if os . name == " nt " :
2011-05-30 09:09:04 +00:00
try :
2012-08-08 07:58:09 +00:00
key = _winreg . OpenKey ( _winreg . HKEY_LOCAL_MACHINE , " HARDWARE \\ DEVICEMAP \\ SERIALCOMM " )
2012-08-08 07:38:48 +00:00
i = 0
2011-05-30 09:09:04 +00:00
while ( 1 ) :
2012-08-08 07:38:48 +00:00
baselist + = [ _winreg . EnumValue ( key , i ) [ 1 ] ]
2011-05-30 09:09:04 +00:00
i + = 1
except :
pass
return baselist + glob . glob ( ' /dev/ttyUSB* ' ) + glob . glob ( ' /dev/ttyACM* ' ) + glob . glob ( " /dev/tty.* " ) + glob . glob ( " /dev/cu.* " ) + glob . glob ( " /dev/rfcomm* " )
2011-05-26 22:16:57 +00:00
def online ( self ) :
2013-04-20 00:42:03 +00:00
self . log ( " \r Printer is now online " )
2013-04-11 02:49:35 +00:00
self . write_prompt ( )
def write_prompt ( self ) :
2013-01-09 23:59:39 +00:00
sys . stdout . write ( self . promptf ( ) )
2011-05-26 22:16:57 +00:00
sys . stdout . flush ( )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def help_help ( self , l ) :
2011-05-26 22:16:57 +00:00
self . do_help ( " " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_gcodes ( self , l ) :
2011-05-26 22:16:57 +00:00
self . help_gcodes ( )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def help_gcodes ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Gcodes are passed through to the printer as they are " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def complete_macro ( self , text , line , begidx , endidx ) :
if ( len ( line . split ( ) ) == 2 and line [ - 1 ] != " " ) or ( len ( line . split ( ) ) == 1 and line [ - 1 ] == " " ) :
2011-06-07 14:34:56 +00:00
return [ i for i in self . macros . keys ( ) if i . startswith ( text ) ]
2012-08-08 07:38:48 +00:00
elif ( len ( line . split ( ) ) == 3 or ( len ( line . split ( ) ) == 2 and line [ - 1 ] == " " ) ) :
2011-06-29 18:50:09 +00:00
return [ i for i in [ " /D " , " /S " ] + self . completenames ( text ) if i . startswith ( text ) ]
2011-06-01 17:00:35 +00:00
else :
return [ ]
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def hook_macro ( self , l ) :
2011-06-08 19:11:59 +00:00
l = l . rstrip ( )
2011-06-07 08:01:41 +00:00
ls = l . lstrip ( )
ws = l [ : len ( l ) - len ( ls ) ] # just leading whitespace
2012-08-08 07:38:48 +00:00
if len ( ws ) == 0 :
2011-06-07 14:31:43 +00:00
self . end_macro ( )
# pass the unprocessed line to regular command processor to not require empty line in .pronsolerc
2011-06-07 08:01:41 +00:00
return self . onecmd ( l )
2011-06-07 14:31:43 +00:00
self . cur_macro_def + = l + " \n "
2012-08-08 06:39:50 +00:00
def end_macro ( self ) :
2011-06-07 14:31:43 +00:00
if self . __dict__ . has_key ( " onecmd " ) : del self . onecmd # remove override
2013-01-09 23:59:39 +00:00
self . in_macro = False
self . prompt = self . promptf ( )
2011-06-08 19:11:59 +00:00
if self . cur_macro_def != " " :
self . macros [ self . cur_macro_name ] = self . cur_macro_def
2012-08-08 07:38:48 +00:00
macro = self . compile_macro ( self . cur_macro_name , self . cur_macro_def )
2012-08-08 07:58:09 +00:00
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 ) )
2011-06-26 21:05:22 +00:00
if not self . processing_rc :
2013-04-10 13:05:08 +00:00
self . log ( " Macro ' " + self . cur_macro_name + " ' defined " )
2011-06-29 18:50:09 +00:00
# save it
2011-07-04 09:02:30 +00:00
if not self . processing_args :
macro_key = " macro " + self . cur_macro_name
macro_def = macro_key
if " \n " in self . cur_macro_def :
macro_def + = " \n "
else :
macro_def + = " "
macro_def + = self . cur_macro_def
2012-08-08 07:38:48 +00:00
self . save_in_rc ( macro_key , macro_def )
2011-06-08 19:11:59 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " Empty macro - cancelled " )
2012-08-08 07:38:48 +00:00
del self . cur_macro_name , self . cur_macro_def
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def compile_macro_line ( self , line ) :
2011-08-04 11:03:35 +00:00
line = line . rstrip ( )
ls = line . lstrip ( )
ws = line [ : len ( line ) - len ( ls ) ] # just leading whitespace
2012-08-08 07:38:48 +00:00
if ls == " " or ls . startswith ( ' # ' ) : return " " # no code
2011-08-04 11:03:35 +00:00
if ls . startswith ( ' ! ' ) :
return ws + ls [ 1 : ] + " \n " # python mode
else :
return ws + ' self.onecmd( " ' + ls + ' " .format(*arg)) \n ' # parametric command mode
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def compile_macro ( self , macro_name , macro_def ) :
2011-08-04 11:03:35 +00:00
if macro_def . strip ( ) == " " :
2013-04-10 13:05:08 +00:00
self . log ( " Empty macro - cancelled " )
2011-08-04 11:03:35 +00:00
return
pycode = " def macro(self,*arg): \n "
if " \n " not in macro_def . strip ( ) :
pycode + = self . compile_macro_line ( " " + macro_def . strip ( ) )
else :
lines = macro_def . split ( " \n " )
for l in lines :
pycode + = self . compile_macro_line ( l )
exec pycode
return macro
2012-08-08 06:39:50 +00:00
2012-08-08 07:58:09 +00:00
def start_macro ( self , macro_name , prev_definition = " " , suppress_instructions = False ) :
2011-07-15 08:12:21 +00:00
if not self . processing_rc and not suppress_instructions :
2013-04-10 13:05:08 +00:00
self . log ( " Enter macro using indented lines, end with empty line " )
2011-07-06 21:19:45 +00:00
self . cur_macro_name = macro_name
self . cur_macro_def = " "
self . onecmd = self . hook_macro # override onecmd temporarily
2013-01-09 23:59:39 +00:00
self . in_macro = False
self . prompt = self . promptf ( )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def delete_macro ( self , macro_name ) :
2011-07-26 14:34:55 +00:00
if macro_name in self . macros . keys ( ) :
2012-08-08 07:58:09 +00:00
delattr ( self . __class__ , " do_ " + macro_name )
2011-07-26 14:34:55 +00:00
del self . macros [ macro_name ]
2013-04-10 13:05:08 +00:00
self . log ( " Macro ' " + macro_name + " ' removed " )
2011-07-26 14:34:55 +00:00
if not self . processing_rc and not self . processing_args :
2012-08-08 07:58:09 +00:00
self . save_in_rc ( " macro " + macro_name , " " )
2011-07-26 14:34:55 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " Macro ' " + macro_name + " ' is not defined " )
2012-08-08 07:38:48 +00:00
def do_macro ( self , args ) :
2011-06-07 14:31:43 +00:00
if args . strip ( ) == " " :
2012-08-08 07:58:09 +00:00
self . print_topics ( " User-defined macros " , self . macros . keys ( ) , 15 , 80 )
2011-06-07 08:01:41 +00:00
return
2012-08-08 07:38:48 +00:00
arglist = args . split ( None , 1 )
2011-06-07 14:31:43 +00:00
macro_name = arglist [ 0 ]
2012-08-08 07:58:09 +00:00
if macro_name not in self . macros and hasattr ( self . __class__ , " do_ " + macro_name ) :
2013-04-10 13:05:08 +00:00
self . log ( " Name ' " + macro_name + " ' is being used by built-in command " )
2011-06-07 08:01:41 +00:00
return
2011-06-07 14:31:43 +00:00
if len ( arglist ) == 2 :
macro_def = arglist [ 1 ]
if macro_def . lower ( ) == " /d " :
2011-07-26 14:34:55 +00:00
self . delete_macro ( macro_name )
2011-06-07 14:31:43 +00:00
return
if macro_def . lower ( ) == " /s " :
self . subhelp_macro ( macro_name )
return
self . cur_macro_def = macro_def
self . cur_macro_name = macro_name
self . end_macro ( )
2011-06-07 08:01:41 +00:00
return
2011-07-06 21:19:45 +00:00
if self . macros . has_key ( macro_name ) :
2012-08-08 07:38:48 +00:00
self . start_macro ( macro_name , self . macros [ macro_name ] )
2011-07-06 21:19:45 +00:00
else :
self . start_macro ( macro_name )
2012-08-08 06:39:50 +00:00
2011-06-07 08:01:41 +00:00
def help_macro ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Define single-line macro: macro <name> <definition> " )
self . log ( " Define multi-line macro: macro <name> " )
self . log ( " Enter macro definition in indented lines. Use {0} .. {N} to substitute macro arguments " )
self . log ( " Enter python code, prefixed with ! Use arg[0] .. arg[N] to substitute macro arguments " )
self . log ( " Delete macro: macro <name> /d " )
self . log ( " Show macro definition: macro <name> /s " )
self . log ( " ' macro ' without arguments displays list of defined macros " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def subhelp_macro ( self , macro_name ) :
2011-06-07 14:31:43 +00:00
if macro_name in self . macros . keys ( ) :
macro_def = self . macros [ macro_name ]
if " \n " in macro_def :
2013-04-10 13:05:08 +00:00
self . log ( " Macro ' " + macro_name + " ' defined as: " )
self . log ( self . macros [ macro_name ] + " ---------------- " )
2011-06-07 14:31:43 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " Macro ' " + macro_name + " ' defined as: ' " + macro_def + " ' " )
2011-06-07 14:31:43 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " Macro ' " + macro_name + " ' is not defined " )
2011-06-29 18:50:09 +00:00
2012-08-08 07:38:48 +00:00
def set ( self , var , str ) :
2011-06-29 18:50:09 +00:00
try :
2012-08-08 07:38:48 +00:00
t = type ( getattr ( self . settings , var ) )
value = self . settings . _set ( var , str )
2011-07-04 09:02:30 +00:00
if not self . processing_rc and not self . processing_args :
2012-08-08 07:58:09 +00:00
self . save_in_rc ( " set " + var , " set %s %s " % ( var , value ) )
2011-06-29 18:50:09 +00:00
except AttributeError :
2013-04-10 13:05:08 +00:00
self . log ( " Unknown variable ' %s ' " % var )
2011-07-27 18:41:27 +00:00
except ValueError , ve :
2013-04-10 13:05:08 +00:00
self . log ( " Bad value for variable ' %s ' , expecting %s ( %s ) " % ( var , repr ( t ) [ 1 : - 1 ] , ve . args [ 0 ] ) )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_set ( self , argl ) :
args = argl . split ( None , 1 )
2011-06-29 18:50:09 +00:00
if len ( args ) < 1 :
for k in [ kk for kk in dir ( self . settings ) if not kk . startswith ( " _ " ) ] :
2013-04-10 13:05:08 +00:00
self . log ( " %s = %s " % ( k , str ( getattr ( self . settings , k ) ) ) )
2011-06-29 18:50:09 +00:00
return
2012-08-08 07:38:48 +00:00
value = getattr ( self . settings , args [ 0 ] )
2011-06-29 18:50:09 +00:00
if len ( args ) < 2 :
try :
2013-04-10 13:05:08 +00:00
self . log ( " %s = %s " % ( args [ 0 ] , getattr ( self . settings , args [ 0 ] ) ) )
2011-06-29 18:50:09 +00:00
except AttributeError :
2013-04-10 13:05:08 +00:00
self . log ( " Unknown variable ' %s ' " % args [ 0 ] )
2011-06-29 18:50:09 +00:00
return
2012-08-08 07:58:09 +00:00
self . set ( args [ 0 ] , args [ 1 ] )
2012-08-08 06:39:50 +00:00
2011-06-29 18:50:09 +00:00
def help_set ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Set variable: set <variable> <value> " )
self . log ( " Show variable: set <variable> " )
self . log ( " ' set ' without arguments displays all variables " )
2011-06-29 18:50:09 +00:00
def complete_set ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
if ( len ( line . split ( ) ) == 2 and line [ - 1 ] != " " ) or ( len ( line . split ( ) ) == 1 and line [ - 1 ] == " " ) :
2011-06-29 18:50:09 +00:00
return [ i for i in dir ( self . settings ) if not i . startswith ( " _ " ) and i . startswith ( text ) ]
2012-08-08 07:38:48 +00:00
elif ( len ( line . split ( ) ) == 3 or ( len ( line . split ( ) ) == 2 and line [ - 1 ] == " " ) ) :
2011-06-29 18:50:09 +00:00
return [ i for i in self . settings . _tabcomplete ( line . split ( ) [ 1 ] ) if i . startswith ( text ) ]
else :
return [ ]
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def postloop ( self ) :
self . p . disconnect ( )
cmd . Cmd . postloop ( self )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def load_rc ( self , rc_filename ) :
self . processing_rc = True
2011-06-01 13:38:22 +00:00
try :
2012-08-08 07:58:09 +00:00
rc = codecs . open ( rc_filename , " r " , " utf-8 " )
2011-07-04 09:02:30 +00:00
self . rc_filename = os . path . abspath ( rc_filename )
2011-06-09 17:03:57 +00:00
for rc_cmd in rc :
if not rc_cmd . lstrip ( ) . startswith ( " # " ) :
self . onecmd ( rc_cmd )
rc . close ( )
2012-08-08 07:58:09 +00:00
if hasattr ( self , " cur_macro_def " ) :
2011-07-04 09:02:30 +00:00
self . end_macro ( )
self . rc_loaded = True
finally :
2012-08-08 07:38:48 +00:00
self . processing_rc = False
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def load_default_rc ( self , rc_filename = " .pronsolerc " ) :
2011-07-04 09:02:30 +00:00
try :
try :
2012-08-08 07:58:09 +00:00
self . load_rc ( os . path . join ( os . path . expanduser ( " ~ " ) , rc_filename ) )
2011-07-04 09:02:30 +00:00
except IOError :
self . load_rc ( rc_filename )
2011-06-01 13:38:22 +00:00
except IOError :
2011-07-18 15:25:05 +00:00
# make sure the filename is initialized
2012-08-08 07:58:09 +00:00
self . rc_filename = os . path . abspath ( os . path . join ( os . path . expanduser ( " ~ " ) , rc_filename ) )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def save_in_rc ( self , key , definition ) :
2011-06-29 18:50:09 +00:00
"""
2012-08-08 06:39:50 +00:00
Saves or updates macro or other definitions in . pronsolerc
2011-06-29 18:50:09 +00:00
key is prefix that determines what is being defined / updated ( e . g . ' macro foo ' )
definition is the full definition ( that is written to file ) . ( e . g . ' macro foo move x 10 ' )
Set key as empty string to just add ( and not overwrite )
Set definition as empty string to remove it from . pronsolerc
To delete line from . pronsolerc , set key as the line contents , and definition as empty string
Only first definition with given key is overwritten .
Updates are made in the same file position .
Additions are made to the end of the file .
"""
2012-08-08 07:38:48 +00:00
rci , rco = None , None
2011-06-29 18:50:09 +00:00
if definition != " " and not definition . endswith ( " \n " ) :
definition + = " \n "
try :
written = False
if os . path . exists ( self . rc_filename ) :
2012-02-13 07:36:00 +00:00
import shutil
2012-08-08 07:38:48 +00:00
shutil . copy ( self . rc_filename , self . rc_filename + " ~bak " )
2012-08-08 07:58:09 +00:00
rci = codecs . open ( self . rc_filename + " ~bak " , " r " , " utf-8 " )
rco = codecs . open ( self . rc_filename , " w " , " utf-8 " )
2012-02-13 07:36:00 +00:00
if rci is not None :
2011-06-29 18:50:09 +00:00
overwriting = False
for rc_cmd in rci :
l = rc_cmd . rstrip ( )
ls = l . lstrip ( )
ws = l [ : len ( l ) - len ( ls ) ] # just leading whitespace
if overwriting and len ( ws ) == 0 :
overwriting = False
if not written and key != " " and rc_cmd . startswith ( key ) and ( rc_cmd + " \n " ) [ len ( key ) ] . isspace ( ) :
overwriting = True
written = True
rco . write ( definition )
if not overwriting :
rco . write ( rc_cmd )
if not rc_cmd . endswith ( " \n " ) : rco . write ( " \n " )
if not written :
rco . write ( definition )
if rci is not None :
rci . close ( )
rco . close ( )
2011-08-12 05:55:13 +00:00
#if definition != "":
2013-04-10 13:05:08 +00:00
# self.log("Saved '"+key+"' to '"+self.rc_filename+"'")
2011-08-12 05:55:13 +00:00
#else:
2013-04-10 13:05:08 +00:00
# self.log("Removed '"+key+"' from '"+self.rc_filename+"'")
2011-07-27 18:41:27 +00:00
except Exception , e :
2013-05-16 10:21:17 +00:00
self . log ( " Saving failed for " , key + " : " , str ( e ) )
2011-06-29 18:50:09 +00:00
finally :
2012-08-08 07:38:48 +00:00
del rci , rco
2012-08-08 06:39:50 +00:00
2011-06-18 09:54:50 +00:00
def preloop ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Welcome to the printer console! Type \" help \" for a list of available commands. " )
2013-01-12 00:02:14 +00:00
self . prompt = self . promptf ( )
2011-05-26 22:16:57 +00:00
cmd . Cmd . preloop ( self )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_connect ( self , l ) :
a = l . split ( )
p = self . scanserial ( )
port = self . settings . port
2011-06-29 18:50:09 +00:00
if ( port == " " or port not in p ) and len ( p ) > 0 :
2012-08-08 07:38:48 +00:00
port = p [ 0 ]
baud = self . settings . baudrate or 115200
2011-06-01 21:42:27 +00:00
if ( len ( a ) > 0 ) :
2012-08-08 07:38:48 +00:00
port = a [ 0 ]
2011-06-01 21:42:27 +00:00
if ( len ( a ) > 1 ) :
2011-06-01 12:42:35 +00:00
try :
2012-08-08 07:38:48 +00:00
baud = int ( a [ 1 ] )
2011-06-01 12:42:35 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " Bad baud value ' " + a [ 1 ] + " ' ignored " )
2012-08-08 07:38:48 +00:00
if len ( p ) == 0 and not port :
2013-04-10 13:05:08 +00:00
self . log ( " No serial ports detected - please specify a port " )
2011-05-26 22:16:57 +00:00
return
2012-08-08 07:38:48 +00:00
if len ( a ) == 0 :
2013-04-10 13:05:08 +00:00
self . log ( " No port specified - connecting to %s at %d bps " % ( port , baud ) )
2011-06-29 18:50:09 +00:00
if port != self . settings . port :
self . settings . port = port
2012-08-08 07:58:09 +00:00
self . save_in_rc ( " set port " , " set port %s " % port )
2011-06-29 18:50:09 +00:00
if baud != self . settings . baudrate :
self . settings . baudrate = baud
2012-08-08 07:58:09 +00:00
self . save_in_rc ( " set baudrate " , " set baudrate %d " % baud )
2011-05-26 22:16:57 +00:00
self . p . connect ( port , baud )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def help_connect ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Connect to printer " )
self . log ( " connect <port> <baudrate> " )
self . log ( " If port and baudrate are not specified, connects to first detected port at 115200bps " )
2012-08-08 07:38:48 +00:00
ports = self . scanserial ( )
2011-05-30 09:53:45 +00:00
if ( len ( ports ) ) :
2013-04-10 13:05:08 +00:00
self . log ( " Available ports: " , " " . join ( ports ) )
2011-05-30 09:53:45 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " No serial ports were automatically found. " )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def complete_connect ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
if ( len ( line . split ( ) ) == 2 and line [ - 1 ] != " " ) or ( len ( line . split ( ) ) == 1 and line [ - 1 ] == " " ) :
2011-05-26 22:16:57 +00:00
return [ i for i in self . scanserial ( ) if i . startswith ( text ) ]
2012-08-08 07:38:48 +00:00
elif ( len ( line . split ( ) ) == 3 or ( len ( line . split ( ) ) == 2 and line [ - 1 ] == " " ) ) :
2011-05-26 22:16:57 +00:00
return [ i for i in [ " 2400 " , " 9600 " , " 19200 " , " 38400 " , " 57600 " , " 115200 " ] if i . startswith ( text ) ]
else :
return [ ]
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_disconnect ( self , l ) :
2011-05-26 22:16:57 +00:00
self . p . disconnect ( )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def help_disconnect ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Disconnects from the printer " )
2012-09-05 08:11:48 +00:00
2011-05-26 22:16:57 +00:00
def do_load ( self , l ) :
2012-09-05 07:56:16 +00:00
self . _do_load ( l )
2012-08-08 06:39:50 +00:00
2012-08-20 02:10:46 +00:00
def _do_load ( self , l ) :
2011-05-28 17:08:22 +00:00
if len ( l ) == 0 :
2013-04-10 13:05:08 +00:00
self . log ( " No file name given. " )
2011-05-28 17:08:22 +00:00
return
2013-04-10 13:05:08 +00:00
self . log ( " Loading file: " + l )
2011-05-26 22:16:57 +00:00
if not ( os . path . exists ( l ) ) :
2013-04-10 13:05:08 +00:00
self . log ( " File not found! " )
2011-05-26 22:16:57 +00:00
return
2012-08-08 07:58:09 +00:00
self . f = [ i . replace ( " \n " , " " ) . replace ( " \r " , " " ) for i in open ( l ) ]
2012-08-08 07:38:48 +00:00
self . filename = l
2013-04-10 13:05:08 +00:00
self . log ( " Loaded " , l , " , " , len ( self . f ) , " lines. " )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def complete_load ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
s = line . split ( )
2011-05-28 17:08:22 +00:00
if len ( s ) > 2 :
return [ ]
2012-08-08 07:38:48 +00:00
if ( len ( s ) == 1 and line [ - 1 ] == " " ) or ( len ( s ) == 2 and line [ - 1 ] != " " ) :
2011-05-26 22:16:57 +00:00
if len ( s ) > 1 :
return [ i [ len ( s [ 1 ] ) - len ( text ) : ] for i in glob . glob ( s [ 1 ] + " */ " ) + glob . glob ( s [ 1 ] + " *.g* " ) ]
else :
return glob . glob ( " */ " ) + glob . glob ( " *.g* " )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def help_load ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Loads a gcode file (with tab-completion) " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_upload ( self , l ) :
if len ( l ) == 0 :
2013-04-10 13:05:08 +00:00
self . log ( " No file name given. " )
2011-05-28 17:08:22 +00:00
return
2013-04-10 13:05:08 +00:00
self . log ( " Loading file: " + l . split ( ) [ 0 ] )
2011-05-28 17:08:22 +00:00
if not ( os . path . exists ( l . split ( ) [ 0 ] ) ) :
2013-04-10 13:05:08 +00:00
self . log ( " File not found! " )
2011-05-28 17:08:22 +00:00
return
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " Not connected to printer. " )
2011-05-28 17:08:22 +00:00
return
2012-08-08 07:58:09 +00:00
self . f = [ i . replace ( " \n " , " " ) for i in open ( l . split ( ) [ 0 ] ) ]
2012-08-08 07:38:48 +00:00
self . filename = l . split ( ) [ 0 ]
2013-04-10 13:05:08 +00:00
self . log ( " Loaded " , l , " , " , len ( self . f ) , " lines. " )
2012-08-08 07:38:48 +00:00
tname = " "
2011-05-28 17:08:22 +00:00
if len ( l . split ( ) ) > 1 :
2012-08-08 07:38:48 +00:00
tname = l . split ( ) [ 1 ]
2011-05-28 17:08:22 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " please enter target name in 8.3 format. " )
2011-05-28 17:08:22 +00:00
return
2013-04-10 13:05:08 +00:00
self . log ( " Uploading as " , tname )
self . log ( ( " Uploading " + self . filename ) )
2011-05-28 17:08:22 +00:00
self . p . send_now ( " M28 " + tname )
2013-04-10 13:05:08 +00:00
self . log ( ( " Press Ctrl-C to interrupt upload. " ) )
2011-05-28 17:08:22 +00:00
self . p . startprint ( self . f )
try :
sys . stdout . write ( " Progress: 00.0 % " )
sys . stdout . flush ( )
time . sleep ( 1 )
while self . p . printing :
time . sleep ( 1 )
sys . stdout . write ( " \b \b \b \b \b %04.1f %% " % ( 100 * float ( self . p . queueindex ) / len ( self . p . mainqueue ) , ) )
sys . stdout . flush ( )
self . p . send_now ( " M29 " + tname )
2011-05-31 15:08:23 +00:00
self . sleep ( 0.2 )
2012-08-08 07:38:48 +00:00
self . p . clear = 1
self . listing = 0
2012-08-08 07:58:09 +00:00
self . sdfiles = [ ]
2011-05-30 13:47:01 +00:00
self . recvlisteners + = [ self . listfiles ]
self . p . send_now ( " M20 " )
time . sleep ( 0.5 )
2013-04-10 13:05:08 +00:00
self . log ( " \b \b \b \b \b 100 % . Upload completed. " , tname , " should now be on the card. " )
2011-05-28 17:08:22 +00:00
return
except :
2013-04-10 13:05:08 +00:00
self . log ( " ...interrupted! " )
2011-05-28 17:08:22 +00:00
self . p . pause ( )
self . p . send_now ( " M29 " + tname )
2011-06-01 21:09:51 +00:00
time . sleep ( 0.2 )
2012-08-08 07:38:48 +00:00
self . p . clear = 1
2011-05-28 17:08:22 +00:00
self . p . startprint ( [ ] )
2013-04-10 13:05:08 +00:00
self . log ( " A partial file named " , tname , " may have been written to the sd card. " )
2012-08-08 06:39:50 +00:00
2011-05-28 17:08:22 +00:00
def complete_upload ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
s = line . split ( )
2011-05-28 17:08:22 +00:00
if len ( s ) > 2 :
return [ ]
2012-08-08 07:38:48 +00:00
if ( len ( s ) == 1 and line [ - 1 ] == " " ) or ( len ( s ) == 2 and line [ - 1 ] != " " ) :
2011-05-28 17:08:22 +00:00
if len ( s ) > 1 :
return [ i [ len ( s [ 1 ] ) - len ( text ) : ] for i in glob . glob ( s [ 1 ] + " */ " ) + glob . glob ( s [ 1 ] + " *.g* " ) ]
else :
return glob . glob ( " */ " ) + glob . glob ( " *.g* " )
2012-08-08 06:39:50 +00:00
2011-05-28 17:08:22 +00:00
def help_upload ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Uploads a gcode file to the sd card " )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def help_print ( self ) :
if self . f is None :
2013-04-10 13:05:08 +00:00
self . log ( " Send a loaded gcode file to the printer. Load a file with the load command first. " )
2011-05-26 22:16:57 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " Send a loaded gcode file to the printer. You have " + self . filename + " loaded right now. " )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def do_print ( self , l ) :
if self . f is None :
2013-04-10 13:05:08 +00:00
self . log ( " No file loaded. Please use load first. " )
2011-05-26 22:16:57 +00:00
return
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " Not connected to printer. " )
2011-05-26 22:16:57 +00:00
return
2013-04-10 13:05:08 +00:00
self . log ( ( " printing " + self . filename ) )
self . log ( ( " You can monitor the print with the monitor command. " ) )
2011-05-26 22:16:57 +00:00
self . p . startprint ( self . f )
2011-06-02 16:47:45 +00:00
#self.p.pause()
2012-08-08 07:38:48 +00:00
#self.paused = True
2011-06-02 16:47:45 +00:00
#self.do_resume(None)
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_pause ( self , l ) :
2011-06-02 16:47:45 +00:00
if self . sdprinting :
self . p . send_now ( " M25 " )
else :
if ( not self . p . printing ) :
2013-05-01 22:23:05 +00:00
self . log ( " Not printing, cannot pause. " )
2011-06-02 16:47:45 +00:00
return
self . p . pause ( )
2012-08-08 06:39:50 +00:00
#self.p.connect()# This seems to work, but is not a good solution.
2012-08-08 07:38:48 +00:00
self . paused = True
2012-08-08 06:39:50 +00:00
2011-06-02 16:47:45 +00:00
#self.do_resume(None)
2012-08-08 06:39:50 +00:00
2011-06-07 05:46:29 +00:00
def help_pause ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Pauses a running print " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_resume ( self , l ) :
2011-05-26 22:16:57 +00:00
if not self . paused :
2013-04-10 13:05:08 +00:00
self . log ( " Not paused, unable to resume. Start a print first. " )
2011-05-26 22:16:57 +00:00
return
2012-08-08 07:38:48 +00:00
self . paused = False
2011-06-02 16:47:45 +00:00
if self . sdprinting :
self . p . send_now ( " M24 " )
return
else :
self . p . resume ( )
2012-08-08 06:39:50 +00:00
2011-05-28 17:08:22 +00:00
def help_resume ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Resumes a paused print. " )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def emptyline ( self ) :
pass
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_shell ( self , l ) :
2011-05-26 22:16:57 +00:00
exec ( l )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def listfiles ( self , line ) :
2011-05-30 13:47:01 +00:00
if " Begin file list " in line :
2012-08-08 07:38:48 +00:00
self . listing = 1
2011-05-30 13:47:01 +00:00
elif " End file list " in line :
2012-08-08 07:38:48 +00:00
self . listing = 0
2011-05-30 13:47:01 +00:00
self . recvlisteners . remove ( self . listfiles )
elif self . listing :
2012-08-08 07:58:09 +00:00
self . sdfiles + = [ line . replace ( " \n " , " " ) . replace ( " \r " , " " ) . lower ( ) ]
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_ls ( self , l ) :
2011-05-31 07:14:50 +00:00
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. Try connect to it first. " )
2011-05-31 07:14:50 +00:00
return
2012-08-08 07:38:48 +00:00
self . listing = 2
2012-08-08 07:58:09 +00:00
self . sdfiles = [ ]
2011-05-30 13:47:01 +00:00
self . recvlisteners + = [ self . listfiles ]
self . p . send_now ( " M20 " )
time . sleep ( 0.5 )
2013-04-10 13:05:08 +00:00
self . log ( " " . join ( self . sdfiles ) )
2012-08-08 06:39:50 +00:00
2011-05-30 13:47:01 +00:00
def help_ls ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " lists files on the SD card " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def waitforsdresponse ( self , l ) :
2011-05-31 07:14:50 +00:00
if " file.open failed " in l :
2013-04-10 13:05:08 +00:00
self . log ( " Opening file failed. " )
2011-05-31 07:14:50 +00:00
self . recvlisteners . remove ( self . waitforsdresponse )
return
if " File opened " in l :
2013-04-10 13:05:08 +00:00
self . log ( l )
2011-05-31 07:14:50 +00:00
if " File selected " in l :
2013-04-10 13:05:08 +00:00
self . log ( " Starting print " )
2011-05-31 07:14:50 +00:00
self . p . send_now ( " M24 " )
2012-08-08 07:38:48 +00:00
self . sdprinting = 1
2011-05-31 07:14:50 +00:00
#self.recvlisteners.remove(self.waitforsdresponse)
return
if " Done printing file " in l :
2013-04-10 13:05:08 +00:00
self . log ( l )
2012-08-08 07:38:48 +00:00
self . sdprinting = 0
2011-05-31 07:14:50 +00:00
self . recvlisteners . remove ( self . waitforsdresponse )
return
2011-06-01 12:32:45 +00:00
if " SD printing byte " in l :
#M27 handler
try :
2012-08-08 07:38:48 +00:00
resp = l . split ( )
vals = resp [ - 1 ] . split ( " / " )
self . percentdone = 100.0 * int ( vals [ 0 ] ) / int ( vals [ 1 ] )
2011-06-01 12:32:45 +00:00
except :
pass
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_reset ( self , l ) :
2011-06-06 17:46:25 +00:00
self . p . reset ( )
2012-08-08 06:39:50 +00:00
2011-06-06 17:46:25 +00:00
def help_reset ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Resets the printer. " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_sdprint ( self , l ) :
2011-05-31 07:14:50 +00:00
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. Try connect to it first. " )
2011-05-31 07:14:50 +00:00
return
2012-08-08 07:38:48 +00:00
self . listing = 2
2012-08-08 07:58:09 +00:00
self . sdfiles = [ ]
2011-05-30 13:47:01 +00:00
self . recvlisteners + = [ self . listfiles ]
self . p . send_now ( " M20 " )
time . sleep ( 0.5 )
if not ( l . lower ( ) in self . sdfiles ) :
2013-04-10 13:05:08 +00:00
self . log ( " File is not present on card. Upload it first " )
2011-05-30 13:47:01 +00:00
return
2011-05-31 07:14:50 +00:00
self . recvlisteners + = [ self . waitforsdresponse ]
2011-05-30 13:47:01 +00:00
self . p . send_now ( " M23 " + l . lower ( ) )
2013-04-10 13:05:08 +00:00
self . log ( " printing file: " + l . lower ( ) + " from SD card. " )
self . log ( " Requesting SD print... " )
2011-05-31 07:14:50 +00:00
time . sleep ( 1 )
2012-08-08 06:39:50 +00:00
2011-05-30 13:47:01 +00:00
def help_sdprint ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " print a file from the SD card. Tabcompletes with available file names. " )
self . log ( " sdprint filename.g " )
2012-08-08 06:39:50 +00:00
2011-05-30 13:47:01 +00:00
def complete_sdprint ( self , text , line , begidx , endidx ) :
2011-05-31 07:14:50 +00:00
if self . sdfiles == [ ] and self . p . online :
2012-08-08 07:38:48 +00:00
self . listing = 2
2011-05-30 13:47:01 +00:00
self . recvlisteners + = [ self . listfiles ]
self . p . send_now ( " M20 " )
time . sleep ( 0.5 )
2012-08-08 07:38:48 +00:00
if ( len ( line . split ( ) ) == 2 and line [ - 1 ] != " " ) or ( len ( line . split ( ) ) == 1 and line [ - 1 ] == " " ) :
2011-05-30 13:47:01 +00:00
return [ i for i in self . sdfiles if i . startswith ( text ) ]
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def recvcb ( self , l ) :
2011-06-01 21:09:51 +00:00
if " T: " in l :
2012-08-08 07:38:48 +00:00
self . tempreadings = l
2013-01-12 00:02:14 +00:00
self . status . update_tempreading ( l )
2012-08-08 07:38:48 +00:00
tstring = l . rstrip ( )
2011-06-09 14:01:23 +00:00
if ( tstring != " ok " and not tstring . startswith ( " ok T " ) and not tstring . startswith ( " T: " ) and not self . listing and not self . monitoring ) :
2013-01-19 23:34:15 +00:00
if tstring [ : 5 ] == " echo: " :
tstring = tstring [ 5 : ] . lstrip ( )
2013-04-20 00:42:03 +00:00
if self . silent == False : print " \r " + tstring . ljust ( 15 )
2013-01-09 23:59:39 +00:00
sys . stdout . write ( self . promptf ( ) )
2011-06-09 14:01:23 +00:00
sys . stdout . flush ( )
2011-05-30 13:47:01 +00:00
for i in self . recvlisteners :
i ( l )
2012-08-08 06:39:50 +00:00
2011-05-26 22:16:57 +00:00
def help_shell ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Executes a python command. Example: " )
self . log ( " ! os.listdir( ' . ' ) " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def default ( self , l ) :
2012-03-01 13:13:57 +00:00
if ( l [ 0 ] in self . commandprefixes . upper ( ) ) :
2011-05-26 22:16:57 +00:00
if ( self . p and self . p . online ) :
2012-08-12 16:20:42 +00:00
if ( not self . p . loud ) :
2013-04-10 13:05:08 +00:00
self . log ( " SENDING: " + l )
2011-05-26 22:16:57 +00:00
self . p . send_now ( l )
2011-05-28 17:08:22 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. " )
2011-05-28 17:08:22 +00:00
return
2012-03-01 13:13:57 +00:00
elif ( l [ 0 ] in self . commandprefixes . lower ( ) ) :
2011-05-26 22:16:57 +00:00
if ( self . p and self . p . online ) :
2012-08-12 16:20:42 +00:00
if ( not self . p . loud ) :
2013-04-10 13:05:08 +00:00
self . log ( " SENDING: " + l . upper ( ) )
2011-05-26 22:16:57 +00:00
self . p . send_now ( l . upper ( ) )
2011-05-28 17:08:22 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. " )
2011-05-28 17:08:22 +00:00
return
2011-05-26 22:16:57 +00:00
else :
2012-08-08 07:38:48 +00:00
cmd . Cmd . default ( self , l )
2012-08-08 06:39:50 +00:00
2011-05-28 17:08:22 +00:00
def help_help ( self ) :
self . do_help ( " " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def tempcb ( self , l ) :
2011-06-05 14:04:38 +00:00
if " T: " in l :
2013-04-10 13:05:08 +00:00
self . log ( l . replace ( " \r " , " " ) . replace ( " T " , " Hotend " ) . replace ( " B " , " Bed " ) . replace ( " \n " , " " ) . replace ( " ok " , " " ) )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_gettemp ( self , l ) :
2013-01-12 19:14:10 +00:00
if " dynamic " in l :
self . dynamic_temp = True
2011-05-31 07:14:50 +00:00
if self . p . online :
self . p . send_now ( " M105 " )
2011-06-06 17:46:25 +00:00
time . sleep ( 0.75 )
2013-01-12 00:02:14 +00:00
if not self . status . bed_enabled :
print " Hotend: %s / %s " % ( self . status . extruder_temp , self . status . extruder_temp_target )
else :
print " Hotend: %s / %s " % ( self . status . extruder_temp , self . status . extruder_temp_target )
print " Bed: %s / %s " % ( self . status . bed_temp , self . status . bed_temp_target )
2012-08-08 06:39:50 +00:00
2011-05-31 07:14:50 +00:00
def help_gettemp ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Read the extruder and bed temperature. " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_settemp ( self , l ) :
2011-05-31 07:14:50 +00:00
try :
2012-08-08 07:58:09 +00:00
l = l . lower ( ) . replace ( " , " , " . " )
2011-06-09 10:54:03 +00:00
for i in self . temps . keys ( ) :
2012-08-08 07:38:48 +00:00
l = l . replace ( i , self . temps [ i ] )
f = float ( l )
2011-05-31 07:14:50 +00:00
if f > = 0 :
2013-02-02 15:25:16 +00:00
if f > 250 :
2013-02-03 02:24:07 +00:00
print f , " is a high temperature to set your extruder to. Are you sure you want to do that? "
2013-02-02 15:25:16 +00:00
if not confirm ( ) :
return
2011-05-31 07:14:50 +00:00
if self . p . online :
self . p . send_now ( " M104 S " + l )
2013-04-10 13:05:08 +00:00
self . log ( " Setting hotend temperature to " , f , " degrees Celsius. " )
2011-05-31 07:14:50 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. " )
2011-05-31 07:14:50 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0. " )
2011-05-31 07:14:50 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " You must enter a temperature. " )
2012-08-08 06:39:50 +00:00
2011-05-31 07:14:50 +00:00
def help_settemp ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Sets the hotend temperature to the value entered. " )
self . log ( " Enter either a temperature in celsius or one of the following keywords " )
self . log ( " , " . join ( [ i + " ( " + self . temps [ i ] + " ) " for i in self . temps . keys ( ) ] ) )
2012-08-08 06:39:50 +00:00
2011-05-31 15:08:23 +00:00
def complete_settemp ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
if ( len ( line . split ( ) ) == 2 and line [ - 1 ] != " " ) or ( len ( line . split ( ) ) == 1 and line [ - 1 ] == " " ) :
2011-05-31 15:08:23 +00:00
return [ i for i in self . temps . keys ( ) if i . startswith ( text ) ]
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_bedtemp ( self , l ) :
2011-05-31 07:14:50 +00:00
try :
2012-08-08 07:58:09 +00:00
l = l . lower ( ) . replace ( " , " , " . " )
2011-06-09 10:54:03 +00:00
for i in self . bedtemps . keys ( ) :
2012-08-08 07:38:48 +00:00
l = l . replace ( i , self . bedtemps [ i ] )
f = float ( l )
2011-05-31 07:14:50 +00:00
if f > = 0 :
if self . p . online :
self . p . send_now ( " M140 S " + l )
2013-04-10 13:05:08 +00:00
self . log ( " Setting bed temperature to " , f , " degrees Celsius. " )
2011-05-31 07:14:50 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. " )
2011-05-31 07:14:50 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0. " )
2011-05-31 07:14:50 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " You must enter a temperature. " )
2012-08-08 06:39:50 +00:00
2011-05-31 07:14:50 +00:00
def help_bedtemp ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Sets the bed temperature to the value entered. " )
self . log ( " Enter either a temperature in celsius or one of the following keywords " )
self . log ( " , " . join ( [ i + " ( " + self . bedtemps [ i ] + " ) " for i in self . bedtemps . keys ( ) ] ) )
2012-08-08 06:39:50 +00:00
2011-05-31 15:08:23 +00:00
def complete_bedtemp ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
if ( len ( line . split ( ) ) == 2 and line [ - 1 ] != " " ) or ( len ( line . split ( ) ) == 1 and line [ - 1 ] == " " ) :
2011-05-31 15:08:23 +00:00
return [ i for i in self . bedtemps . keys ( ) if i . startswith ( text ) ]
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_move ( self , l ) :
2011-06-01 12:32:45 +00:00
if ( len ( l . split ( ) ) < 2 ) :
2013-04-10 13:05:08 +00:00
self . log ( " No move specified. " )
2011-06-01 12:32:45 +00:00
return
if self . p . printing :
2013-04-10 13:05:08 +00:00
self . log ( " printer is currently printing. Please pause the print before you issue manual commands. " )
2011-06-01 12:32:45 +00:00
return
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. Unable to move. " )
2011-06-01 12:32:45 +00:00
return
2012-08-08 07:38:48 +00:00
l = l . split ( )
2011-06-01 12:32:45 +00:00
if ( l [ 0 ] . lower ( ) == " x " ) :
2012-08-08 07:38:48 +00:00
feed = self . settings . xy_feedrate
axis = " X "
2011-06-01 12:32:45 +00:00
elif ( l [ 0 ] . lower ( ) == " y " ) :
2012-08-08 07:38:48 +00:00
feed = self . settings . xy_feedrate
axis = " Y "
2011-06-01 12:32:45 +00:00
elif ( l [ 0 ] . lower ( ) == " z " ) :
2012-08-08 07:38:48 +00:00
feed = self . settings . z_feedrate
axis = " Z "
2011-06-01 12:32:45 +00:00
elif ( l [ 0 ] . lower ( ) == " e " ) :
2012-08-08 07:38:48 +00:00
feed = self . settings . e_feedrate
axis = " E "
2011-06-01 12:32:45 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " Unknown axis. " )
2011-06-01 12:32:45 +00:00
return
2012-08-08 07:38:48 +00:00
dist = 0
2011-06-01 12:32:45 +00:00
try :
2012-08-08 07:38:48 +00:00
dist = float ( l [ 1 ] )
2011-06-01 12:32:45 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " Invalid distance " )
2011-06-01 12:32:45 +00:00
return
2011-06-09 16:44:57 +00:00
try :
2012-08-08 07:38:48 +00:00
feed = int ( l [ 2 ] )
2011-06-09 16:44:57 +00:00
except :
pass
2011-06-01 12:32:45 +00:00
self . p . send_now ( " G91 " )
self . p . send_now ( " G1 " + axis + str ( l [ 1 ] ) + " F " + str ( feed ) )
self . p . send_now ( " G90 " )
2012-08-08 06:39:50 +00:00
2011-06-01 12:32:45 +00:00
def help_move ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Move an axis. Specify the name of the axis and the amount. " )
self . log ( " move X 10 will move the X axis forward by 10mm at " , self . settings . xy_feedrate , " mm/min (default XY speed) " )
self . log ( " move Y 10 5000 will move the Y axis forward by 10mm at 5000mm/min " )
self . log ( " move Z -1 will move the Z axis down by 1mm at " , self . settings . z_feedrate , " mm/min (default Z speed) " )
self . log ( " Common amounts are in the tabcomplete list. " )
2012-08-08 06:39:50 +00:00
2011-06-01 12:32:45 +00:00
def complete_move ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
if ( len ( line . split ( ) ) == 2 and line [ - 1 ] != " " ) or ( len ( line . split ( ) ) == 1 and line [ - 1 ] == " " ) :
2012-08-08 07:58:09 +00:00
return [ i for i in [ " X " , " Y " , " Z " , " E " ] if i . lower ( ) . startswith ( text ) ]
2012-08-08 07:38:48 +00:00
elif ( len ( line . split ( ) ) == 3 or ( len ( line . split ( ) ) == 2 and line [ - 1 ] == " " ) ) :
base = line . split ( ) [ - 1 ]
rlen = 0
2011-06-01 12:32:45 +00:00
if base . startswith ( " - " ) :
2012-08-08 07:38:48 +00:00
rlen = 1
2011-06-01 12:32:45 +00:00
if line [ - 1 ] == " " :
2012-08-08 07:38:48 +00:00
base = " "
2012-08-08 07:58:09 +00:00
return [ i [ rlen : ] for i in [ " -100 " , " -10 " , " -1 " , " -0.1 " , " 100 " , " 10 " , " 1 " , " 0.1 " , " -50 " , " -5 " , " -0.5 " , " 50 " , " 5 " , " 0.5 " , " -200 " , " -20 " , " -2 " , " -0.2 " , " 200 " , " 20 " , " 2 " , " 0.2 " ] if i . startswith ( base ) ]
2011-06-01 12:32:45 +00:00
else :
return [ ]
2012-08-08 06:39:50 +00:00
2012-08-08 07:58:09 +00:00
def do_extrude ( self , l , override = None , overridefeed = 300 ) :
2012-08-08 07:38:48 +00:00
length = 5 #default extrusion length
feed = self . settings . e_feedrate #default speed
2011-06-01 12:32:45 +00:00
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. Unable to move. " )
2011-06-01 12:32:45 +00:00
return
if self . p . printing :
2013-04-10 13:05:08 +00:00
self . log ( " printer is currently printing. Please pause the print before you issue manual commands. " )
2011-06-01 12:32:45 +00:00
return
2012-08-08 07:38:48 +00:00
ls = l . split ( )
2011-06-01 12:32:45 +00:00
if len ( ls ) :
try :
2012-08-08 07:38:48 +00:00
length = float ( ls [ 0 ] )
2011-06-01 12:32:45 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " Invalid length given. " )
2011-06-02 17:59:20 +00:00
if len ( ls ) > 1 :
try :
2012-08-08 07:38:48 +00:00
feed = int ( ls [ 1 ] )
2011-06-02 17:59:20 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " Invalid speed given. " )
2011-06-01 12:32:45 +00:00
if override is not None :
2012-08-08 07:38:48 +00:00
length = override
feed = overridefeed
2011-06-01 12:32:45 +00:00
if length > 0 :
2013-04-10 13:05:08 +00:00
self . log ( " Extruding %f mm of filament. " % ( length , ) )
2011-06-01 12:32:45 +00:00
elif length < 0 :
2013-04-10 13:05:08 +00:00
self . log ( " Reversing %f mm of filament. " % ( - 1 * length , ) )
2011-06-01 12:32:45 +00:00
else :
" Length is 0, not doing anything. "
self . p . send_now ( " G91 " )
self . p . send_now ( " G1 E " + str ( length ) + " F " + str ( feed ) )
self . p . send_now ( " G90 " )
2012-08-08 06:39:50 +00:00
2011-06-01 12:32:45 +00:00
def help_extrude ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Extrudes a length of filament, 5mm by default, or the number of mm given as a parameter " )
self . log ( " extrude - extrudes 5mm of filament at 300mm/min (5mm/s) " )
self . log ( " extrude 20 - extrudes 20mm of filament at 300mm/min (5mm/s) " )
self . log ( " extrude -5 - REVERSES 5mm of filament at 300mm/min (5mm/s) " )
self . log ( " extrude 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s) " )
2012-08-08 06:39:50 +00:00
2011-06-01 12:32:45 +00:00
def do_reverse ( self , l ) :
2012-08-08 07:38:48 +00:00
length = 5 #default extrusion length
feed = self . settings . e_feedrate #default speed
2011-06-01 12:32:45 +00:00
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. Unable to move. " )
2011-06-01 12:32:45 +00:00
return
if self . p . printing :
2013-04-10 13:05:08 +00:00
self . log ( " printer is currently printing. Please pause the print before you issue manual commands. " )
2011-06-01 12:32:45 +00:00
return
2012-08-08 07:38:48 +00:00
ls = l . split ( )
2011-06-01 12:32:45 +00:00
if len ( ls ) :
try :
2012-08-08 07:38:48 +00:00
length = float ( ls [ 0 ] )
2011-06-01 12:32:45 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " Invalid length given. " )
2011-06-01 12:32:45 +00:00
if len ( ls ) > 1 :
try :
2012-08-08 07:38:48 +00:00
feed = int ( ls [ 1 ] )
2011-06-01 12:32:45 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " Invalid speed given. " )
2012-08-08 07:58:09 +00:00
self . do_extrude ( " " , length * - 1.0 , feed )
2012-08-08 06:39:50 +00:00
2011-06-01 12:32:45 +00:00
def help_reverse ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Reverses the extruder, 5mm by default, or the number of mm given as a parameter " )
self . log ( " reverse - reverses 5mm of filament at 300mm/min (5mm/s) " )
self . log ( " reverse 20 - reverses 20mm of filament at 300mm/min (5mm/s) " )
self . log ( " reverse 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s) " )
self . log ( " reverse -5 - EXTRUDES 5mm of filament at 300mm/min (5mm/s) " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_exit ( self , l ) :
2013-02-08 16:46:35 +00:00
if self . status . extruder_temp_target != 0 :
print " Setting extruder temp to 0 "
self . p . send_now ( " M104 S0.0 " )
if self . status . bed_enabled :
if self . status . bed_temp_taret != 0 :
print " Setting bed temp to 0 "
self . p . send_now ( " M140 S0.0 " )
2013-04-10 13:05:08 +00:00
self . log ( " Disconnecting from printer... " )
2013-02-03 02:24:07 +00:00
print self . p . printing
if self . p . printing :
print " Are you sure you want to exit while printing? "
print " (this will terminate the print). "
if not confirm ( ) :
return False
2013-04-10 13:05:08 +00:00
self . log ( " Exiting program. Goodbye! " )
2013-02-03 02:24:07 +00:00
self . p . disconnect ( )
2011-06-01 12:32:45 +00:00
return True
2012-08-08 06:39:50 +00:00
2011-06-01 12:32:45 +00:00
def help_exit ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Disconnects from the printer and exits the program. " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_monitor ( self , l ) :
interval = 5
2011-06-01 12:32:45 +00:00
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. Please connect first. " )
2011-06-01 12:32:45 +00:00
return
2013-01-20 00:11:04 +00:00
if not ( self . p . printing or self . sdprinting ) :
2013-04-20 00:42:03 +00:00
self . log ( " Printer not printing. Please print something before monitoring. " )
2013-01-20 00:11:04 +00:00
return
2013-04-10 13:05:08 +00:00
self . log ( " Monitoring printer, use ^C to interrupt. " )
2011-06-01 12:32:45 +00:00
if len ( l ) :
try :
2012-08-08 07:38:48 +00:00
interval = float ( l )
2011-06-01 12:32:45 +00:00
except :
2013-04-10 13:05:08 +00:00
self . log ( " Invalid period given. " )
self . log ( " Updating values every %f seconds. " % ( interval , ) )
2012-08-08 07:38:48 +00:00
self . monitoring = 1
2013-01-20 00:11:04 +00:00
prev_msg_len = 0
2011-06-01 12:32:45 +00:00
try :
2013-01-20 00:11:04 +00:00
while True :
2011-06-01 12:32:45 +00:00
self . p . send_now ( " M105 " )
if ( self . sdprinting ) :
self . p . send_now ( " M27 " )
2011-06-06 17:46:25 +00:00
time . sleep ( interval )
2012-08-08 07:58:09 +00:00
#print (self.tempreadings.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", ""))
2013-01-20 00:11:04 +00:00
if self . p . printing :
preface = " Print progress: "
progress = 100 * float ( self . p . queueindex ) / len ( self . p . mainqueue )
elif self . sdprinting :
preface = " Print progress: "
progress = self . percentdone
progress = int ( progress * 10 ) / 10.0 #limit precision
prev_msg = preface + str ( progress ) + " % "
2013-04-20 00:42:03 +00:00
if self . silent == False :
sys . stdout . write ( " \r " + prev_msg . ljust ( prev_msg_len ) )
sys . stdout . flush ( )
2013-01-20 00:11:04 +00:00
prev_msg_len = len ( prev_msg )
except KeyboardInterrupt :
2013-04-20 00:42:03 +00:00
if self . silent == False : print " Done monitoring. "
2012-08-08 07:38:48 +00:00
self . monitoring = 0
2012-08-08 06:39:50 +00:00
2011-06-01 12:32:45 +00:00
def help_monitor ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Monitor a machine ' s temperatures and an SD print ' s status. " )
self . log ( " monitor - Reports temperature and SD print status (if SD printing) every 5 seconds " )
self . log ( " monitor 2 - Reports temperature and SD print status (if SD printing) every 2 seconds " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def expandcommand ( self , c ) :
2012-08-08 07:58:09 +00:00
return c . replace ( " $python " , sys . executable )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_skein ( self , l ) :
l = l . split ( )
if len ( l ) == 0 :
2013-04-10 13:05:08 +00:00
self . log ( " No file name given. " )
2011-06-01 16:27:25 +00:00
return
2012-08-08 07:38:48 +00:00
settings = 0
2011-06-02 16:47:45 +00:00
if ( l [ 0 ] == " set " ) :
2012-08-08 07:38:48 +00:00
settings = 1
2011-06-02 16:47:45 +00:00
else :
2013-04-10 13:05:08 +00:00
self . log ( " Skeining file: " + l [ 0 ] )
2011-06-02 16:47:45 +00:00
if not ( os . path . exists ( l [ 0 ] ) ) :
2013-04-10 13:05:08 +00:00
self . log ( " File not found! " )
2011-06-02 16:47:45 +00:00
return
2011-06-01 16:27:25 +00:00
try :
2011-11-18 08:52:16 +00:00
import shlex
2011-06-02 16:47:45 +00:00
if ( settings ) :
2012-08-08 07:58:09 +00:00
param = self . expandcommand ( self . settings . sliceoptscommand ) . replace ( " \\ " , " \\ \\ " ) . encode ( )
2013-04-10 13:05:08 +00:00
self . log ( " Entering slicer settings: " , param )
2011-11-18 08:52:16 +00:00
subprocess . call ( shlex . split ( param ) )
2011-06-02 16:47:45 +00:00
else :
2011-12-22 10:07:52 +00:00
param = self . expandcommand ( self . settings . slicecommand ) . encode ( )
2013-04-10 13:05:08 +00:00
self . log ( " Slicing: " , param )
2012-08-08 07:58:09 +00:00
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 ( ) ) ]
2011-12-22 10:07:52 +00:00
subprocess . call ( params )
2013-04-10 13:05:08 +00:00
self . log ( " Loading sliced file. " )
2012-08-08 07:58:09 +00:00
self . do_load ( l [ 0 ] . replace ( " .stl " , " _export.gcode " ) )
2012-08-08 07:38:48 +00:00
except Exception , e :
2013-04-10 13:05:08 +00:00
self . log ( " Skeinforge execution failed: " , e )
2012-08-08 06:39:50 +00:00
2011-06-01 16:27:25 +00:00
def complete_skein ( self , text , line , begidx , endidx ) :
2012-08-08 07:38:48 +00:00
s = line . split ( )
2011-06-01 16:27:25 +00:00
if len ( s ) > 2 :
return [ ]
2012-08-08 07:38:48 +00:00
if ( len ( s ) == 1 and line [ - 1 ] == " " ) or ( len ( s ) == 2 and line [ - 1 ] != " " ) :
2011-06-01 16:27:25 +00:00
if len ( s ) > 1 :
return [ i [ len ( s [ 1 ] ) - len ( text ) : ] for i in glob . glob ( s [ 1 ] + " */ " ) + glob . glob ( s [ 1 ] + " *.stl " ) ]
else :
return glob . glob ( " */ " ) + glob . glob ( " *.stl " )
2012-08-08 06:39:50 +00:00
2011-06-01 16:27:25 +00:00
def help_skein ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Creates a gcode file from an stl model using the slicer (with tab-completion) " )
self . log ( " skein filename.stl - create gcode file " )
self . log ( " skein filename.stl view - create gcode file and view using skeiniso " )
self . log ( " skein set - adjust slicer settings " )
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
def do_home ( self , l ) :
2011-06-09 06:01:09 +00:00
if not self . p . online :
2013-04-10 13:05:08 +00:00
self . log ( " printer is not online. Unable to move. " )
2011-06-09 06:01:09 +00:00
return
if self . p . printing :
2013-04-10 13:05:08 +00:00
self . log ( " printer is currently printing. Please pause the print before you issue manual commands. " )
2011-06-09 06:01:09 +00:00
return
if " x " in l . lower ( ) :
2011-07-28 10:07:47 +00:00
self . p . send_now ( " G28 X0 " )
2011-06-09 06:01:09 +00:00
if " y " in l . lower ( ) :
2011-07-28 10:07:47 +00:00
self . p . send_now ( " G28 Y0 " )
2011-06-09 06:01:09 +00:00
if " z " in l . lower ( ) :
2011-07-28 10:07:47 +00:00
self . p . send_now ( " G28 Z0 " )
2011-06-11 17:32:11 +00:00
if " e " in l . lower ( ) :
self . p . send_now ( " G92 E0 " )
2011-06-09 06:01:09 +00:00
if not len ( l ) :
2011-06-09 06:48:50 +00:00
self . p . send_now ( " G28 " )
2011-06-11 17:32:11 +00:00
self . p . send_now ( " G92 E0 " )
2012-08-08 06:39:50 +00:00
2011-06-09 06:01:09 +00:00
def help_home ( self ) :
2013-04-10 13:05:08 +00:00
self . log ( " Homes the printer " )
self . log ( " home - homes all axes and zeroes the extruder(Using G28 and G92) " )
self . log ( " home xy - homes x and y axes (Using G28) " )
self . log ( " home z - homes z axis only (Using G28) " )
self . log ( " home e - set extruder position to zero (Using G92) " )
self . log ( " home xyze - homes all axes and zeroes the extruder (Using G28 and G92) " )
2012-08-08 06:39:50 +00:00
2013-05-17 15:04:41 +00:00
def add_cmdline_arguments ( self , parser ) :
2013-05-16 10:21:37 +00:00
parser . add_argument ( ' -c ' , ' --conf ' , ' --config ' , help = _ ( " load this file on startup instead of .pronsolerc ; you may chain config files, if so settings auto-save will use the last specified file " ) , action = " append " , default = [ ] )
parser . add_argument ( ' -e ' , ' --execute ' , help = _ ( " executes command after configuration/.pronsolerc is loaded ; macros/settings from these commands are not autosaved " ) , action = " append " , default = [ ] )
parser . add_argument ( ' filename ' , nargs = ' ? ' , help = _ ( " file to load " ) )
2013-05-17 15:04:41 +00:00
def process_cmdline_arguments ( self , args ) :
2013-05-16 10:21:37 +00:00
for config in args . conf :
self . load_rc ( config )
2011-07-04 10:06:42 +00:00
if not self . rc_loaded :
self . load_default_rc ( )
2013-05-16 10:21:37 +00:00
self . processing_args = True
for command in args . execute :
self . onecmd ( command )
self . processing_args = False
if args . filename :
self . do_load ( args . filename )
2013-01-12 00:26:04 +00:00
2013-05-17 15:04:41 +00:00
def parse_cmdline ( self , args ) :
parser = argparse . ArgumentParser ( description = ' Printrun 3D printer interface ' )
self . add_cmdline_arguments ( parser )
args = parser . parse_args ( )
self . process_cmdline_arguments ( args )
2013-01-12 00:26:04 +00:00
# We replace this function, defined in cmd.py .
# It's default behavior with reagrds to Ctr-C
# and Ctr-D doesn't make much sense...
def cmdloop ( self , intro = None ) :
""" Repeatedly issue a prompt, accept input, parse an initial prefix
off the received input , and dispatch to action methods , passing them
the remainder of the line as argument .
"""
self . preloop ( )
if self . use_rawinput and self . completekey :
try :
import readline
self . old_completer = readline . get_completer ( )
readline . set_completer ( self . complete )
readline . parse_and_bind ( self . completekey + " : complete " )
except ImportError :
pass
try :
if intro is not None :
self . intro = intro
if self . intro :
self . stdout . write ( str ( self . intro ) + " \n " )
stop = None
while not stop :
if self . cmdqueue :
line = self . cmdqueue . pop ( 0 )
else :
if self . use_rawinput :
try :
line = raw_input ( self . prompt )
except EOFError :
print " "
2013-02-03 02:24:07 +00:00
should_exit = self . do_exit ( " " )
if should_exit :
exit ( )
2013-01-12 00:26:04 +00:00
except KeyboardInterrupt :
print " "
line = " "
else :
self . stdout . write ( self . prompt )
self . stdout . flush ( )
line = self . stdin . readline ( )
if not len ( line ) :
line = " "
else :
line = line . rstrip ( ' \r \n ' )
line = self . precmd ( line )
stop = self . onecmd ( line )
stop = self . postcmd ( stop , line )
self . postloop ( )
finally :
if self . use_rawinput and self . completekey :
try :
import readline
readline . set_completer ( self . old_completer )
except ImportError :
pass
2012-08-08 07:38:48 +00:00
if __name__ == " __main__ " :
2012-08-08 06:39:50 +00:00
2012-08-08 07:38:48 +00:00
interp = pronsole ( )
2011-07-04 09:02:30 +00:00
interp . parse_cmdline ( sys . argv [ 1 : ] )
2011-06-09 06:01:09 +00:00
try :
interp . cmdloop ( )
except :
interp . p . disconnect ( )
2011-06-11 21:03:01 +00:00
#raise