I'm trying to modify this python application{- https://github.com/kliment/Printrun/blob/master/pronsole.py which is used for controlling 3D printers. Basically I'm trying to take the command line version of the app and add udp reception, so I can control it from an iphone app I made. I have the python app receiving the udp fine, deciphering the different messages it receives, etc. This python script has a class in it which defines all the methods used. This is a very stripped down version of it, with the method that is giving me problems-
class pronsole(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
if not READLINE:
self.completekey = None
self.p = printcore.printcore()
self.p.recvcb = self.recvcb
self.recvlisteners = []
self.prompt = "PC>"
self.p.onlinecb = self.online
self.f = None
...
def do_connect(self, l):
a = l.split()
p = self.scanserial()
port = self.settings.port
if (port == "" or port not in p) and len(p)>0:
port = p[0]
baud = self.settings.baudrate or 115200
if(len(a)>0):
port = a[0]
if(len(a)>1):
try:
baud = int(a[1])
except:
print "Bad baud value '"+a[1]+"' ignored"
if len(p) == 0 and not port:
print "No serial ports detected - please specify a port"
return
if len(a) == 0:
print "No port specified - connecting to %s at %dbps" % (port, baud)
if port != self.settings.port:
self.settings.port = port
self.save_in_rc("set port", "set port %s" % port)
if baud != self.settings.baudrate:
self.settings.baudrate = baud
self.save_in_rc("set baudrate", "set baudrate %d" % baud)
self.p.connect(port, baud)
There is another method in the class called 'do_move' which moves the printer, and I am calling that method when udp is received. I think I am calling it correctly-
a = pronsole()
a.do_move("X 29")
Its trying to call it, but can't do it because I haven't yet connected to the printer. So I tried calling-
a = pronsole()
a.do_connect("")
at the end of the class, but I get the error message- "Saving failed for set port: pronsole instance has no attribute 'rc_filename'"
The method that's trying to use 'rc_filename' is this-
def save_in_rc(self, key, definition):
"""
Saves or updates macro or other definitions in .pronsolerc
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.
"""
rci, rco = None, None
if definition != "" and not definition.endswith("\n"):
definition += "\n"
try:
written = False
if os.path.exists(self.rc_filename):
import shutil
shutil.copy(self.rc_filename, self.rc_filename+"~bak")
rci = codecs.open(self.rc_filename+"~bak", "r", "utf-8")
rco = codecs.open(self.rc_filename, "w", "utf-8")
if rci is not None:
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()
#if definition != "":
# print "Saved '"+key+"' to '"+self.rc_filename+"'"
#else:
# print "Removed '"+key+"' from '"+self.rc_filename+"'"
except Exception, e:
print "Saving failed for", key+":", str(e)
finally:
del rci, rco
I've tried calling the do_connect method via command line, and that works, so I couldn't understand why I couldn't call it within the python script the same way. I'm guessing it has something to do with the fact that I'm referencing an instance of pronsole when I do it-
a = pronsole()
a.do_connect("")
I've tried making it a static method, but that creates other problems. So my question is, what can I do to call this 'do_connect' method from with the python script? Like I said, I'm a python noob; I've had some good sucess figuring out how to get udp working and integrated, but I'm stuck on this one thing that I have a feeling is really simple. Any help would be greatly appreciated.
1 Answer 1
I wanted to do this recently as well and solved it by piping the output from a python script into the pronsole.py program.
So rather than modifying the pronsole code, I implemented all of my socket functionality in another python program and sent the commands to pronsole via stdout. My program was called 'pronsole_interface', so from the command line I called it like this:
python pronsole_interface.py | pronsole.py
pronsole, when you could just use the methods fromprintrun.pronsoleis designed for interactive use, so using it non-interactively is likely to be tricky.