Merging experimental branch with Pronserve
commit
31891fa3da
|
@ -0,0 +1,213 @@
|
|||
# This file is part of the Printrun suite.
|
||||
#
|
||||
# Copyright 2013 Francesco Santini francesco.santini@gmail.com
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This code is imported from RepetierHost - Original copyright and license:
|
||||
# Copyright 2011 repetier repetierdev@gmail.com
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import re
|
||||
|
||||
class GCodeAnalyzer():
|
||||
def __init__(self):
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.z = 0
|
||||
self.e = 0
|
||||
self.emax = 0
|
||||
self.f = 1000
|
||||
self.lastX = 0
|
||||
self.lastY = 0
|
||||
self.lastZ = 0
|
||||
self.lastE = 0
|
||||
self.xOffset = 0
|
||||
self.yOffset = 0
|
||||
self.zOffset = 0
|
||||
self.eOffset = 0
|
||||
self.lastZPrint = 0
|
||||
self.layerZ = 0
|
||||
self.relative = False
|
||||
self.eRelative = False
|
||||
self.homeX = 0
|
||||
self.homeY = 0
|
||||
self.homeZ = 0
|
||||
self.maxX = 150
|
||||
self.maxY = 150
|
||||
self.maxZ = 150
|
||||
self.minX = 0
|
||||
self.minY = 0
|
||||
self.minZ = 0
|
||||
self.hasHomeX = False
|
||||
self.hasHomeY = False
|
||||
self.hasHomeZ = False
|
||||
|
||||
|
||||
# find a code in a gstring line
|
||||
def findCode(self, gcode, codeStr):
|
||||
pattern = re.compile(codeStr + "\\s*(-?[\d.]*)",re.I)
|
||||
m=re.search(pattern, gcode)
|
||||
if m == None:
|
||||
return None
|
||||
else:
|
||||
return m.group(1)
|
||||
|
||||
def Analyze(self, gcode):
|
||||
gcode = gcode[:gcode.find(";")].lstrip() # remove comments
|
||||
if gcode.startswith("@"): return # code is a host command
|
||||
code_g = self.findCode(gcode, "G")
|
||||
code_m = self.findCode(gcode, "M")
|
||||
# we have a g_code
|
||||
if code_g != None:
|
||||
code_g = int(code_g)
|
||||
|
||||
#get movement codes
|
||||
if code_g == 0 or code_g == 1 or code_g == 2 or code_g == 3:
|
||||
self.lastX = self.x
|
||||
self.lastY = self.y
|
||||
self.lastZ = self.z
|
||||
self.lastE = self.e
|
||||
eChanged = False;
|
||||
code_f = self.findCode(gcode, "F")
|
||||
if code_f != None:
|
||||
self.f=float(code_f)
|
||||
|
||||
code_x = self.findCode(gcode, "X")
|
||||
code_y = self.findCode(gcode, "Y")
|
||||
code_z = self.findCode(gcode, "Z")
|
||||
code_e = self.findCode(gcode, "E")
|
||||
|
||||
if self.relative:
|
||||
if code_x != None: self.x += float(code_x)
|
||||
if code_y != None: self.y += float(code_y)
|
||||
if code_z != None: self.z += float(code_z)
|
||||
if code_e != None:
|
||||
e = float(code_e)
|
||||
if e != 0:
|
||||
eChanged = True
|
||||
self.e += e
|
||||
else:
|
||||
#absolute coordinates
|
||||
if code_x != None: self.x = self.xOffset + float(code_x)
|
||||
if code_y != None: self.y = self.yOffset + float(code_y)
|
||||
if code_z != None: self.z = self.zOffset + float(code_z)
|
||||
if code_e != None:
|
||||
e = float(code_e)
|
||||
if self.eRelative:
|
||||
if e != 0:
|
||||
eChanged = True
|
||||
self.e += e
|
||||
else:
|
||||
# e is absolute. Is it changed?
|
||||
if self.e != self.eOffset + e:
|
||||
eChanged = True
|
||||
self.e = self.eOffset + e
|
||||
#limit checking
|
||||
if self.x < self.minX: self.x = self.minX
|
||||
if self.y < self.minY: self.y = self.minY
|
||||
if self.z < self.minZ: self.z = self.minZ
|
||||
|
||||
if self.x > self.maxX: self.x = self.maxX
|
||||
if self.y > self.maxY: self.y = self.maxY
|
||||
if self.z > self.maxZ: self.z = self.maxZ
|
||||
#Repetier has a bunch of limit-checking code here and time calculations: we are leaving them for now
|
||||
elif code_g == 28 or code_g == 161:
|
||||
self.lastX = self.x
|
||||
self.lastY = self.y
|
||||
self.lastZ = self.z
|
||||
self.lastE = self.e
|
||||
code_x = self.findCode(gcode, "X")
|
||||
code_y = self.findCode(gcode, "Y")
|
||||
code_z = self.findCode(gcode, "Z")
|
||||
code_e = self.findCode(gcode, "E")
|
||||
homeAll = False
|
||||
if code_x == None and code_y == None and code_z == None: homeAll = True
|
||||
if code_x != None or homeAll:
|
||||
self.hasHomeX = True
|
||||
self.xOffset = 0
|
||||
self.x = self.homeX
|
||||
if code_y != None or homeAll:
|
||||
self.hasHomeY = True
|
||||
self.yOffset = 0
|
||||
self.y = self.homeY
|
||||
if code_z != None or homeAll:
|
||||
self.hasHomeZ = True
|
||||
self.zOffset = 0
|
||||
self.z = self.homeZ
|
||||
if code_e != None:
|
||||
self.eOffset = 0
|
||||
self.e = 0
|
||||
elif code_g == 162:
|
||||
self.lastX = self.x
|
||||
self.lastY = self.y
|
||||
self.lastZ = self.z
|
||||
self.lastE = self.e
|
||||
code_x = self.findCode(gcode, "X")
|
||||
code_y = self.findCode(gcode, "Y")
|
||||
code_z = self.findCode(gcode, "Z")
|
||||
homeAll = False
|
||||
if code_x == None and code_y == None and code_z == None: homeAll = True
|
||||
if code_x != None or homeAll:
|
||||
self.hasHomeX = True
|
||||
self.xOffset = 0
|
||||
self.x = self.maxX
|
||||
if code_y != None or homeAll:
|
||||
self.hasHomeY = True
|
||||
self.yOffset = 0
|
||||
self.y = self.maxY
|
||||
if code_z != None or homeAll:
|
||||
self.hasHomeZ = True
|
||||
self.zOffset = 0
|
||||
self.z = self.maxZ
|
||||
elif code_g == 90: self.relative = False
|
||||
elif code_g == 91: self.relative = True
|
||||
elif code_g == 92:
|
||||
code_x = self.findCode(gcode, "X")
|
||||
code_y = self.findCode(gcode, "Y")
|
||||
code_z = self.findCode(gcode, "Z")
|
||||
code_e = self.findCode(gcode, "E")
|
||||
if code_x != None:
|
||||
self.xOffset = self.x - float(code_x)
|
||||
self.x = self.xOffset
|
||||
if code_y != None:
|
||||
self.yOffset = self.y - float(code_y)
|
||||
self.y = self.yOffset
|
||||
if code_z != None:
|
||||
self.zOffset = self.z - float(code_z)
|
||||
self.z = self.zOffset
|
||||
if code_e != None:
|
||||
self.xOffset = self.e - float(code_e)
|
||||
self.e = self.eOffset
|
||||
#End code_g != None
|
||||
if code_m != None:
|
||||
code_m = int(code_m)
|
||||
if code_m == 82: self.eRelative = False
|
||||
elif code_m == 83: self.eRelative = True
|
||||
|
||||
def print_status(self):
|
||||
attrs = vars(self)
|
||||
print '\n'.join("%s: %s" % item for item in attrs.items())
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
250
gcoder.py
250
gcoder.py
|
@ -16,6 +16,17 @@
|
|||
|
||||
import sys
|
||||
import re
|
||||
import math
|
||||
|
||||
def deltalen(a,b):
|
||||
d = object()
|
||||
d.x = b.x - a.x
|
||||
d.y = b.y - a.y
|
||||
d.z = b.z - a.z
|
||||
|
||||
return math.sqrt((d.x*d.x)+(d.y*d.y)+(d.z*d.z))
|
||||
|
||||
|
||||
|
||||
class Line(object):
|
||||
def __init__(self,l):
|
||||
|
@ -29,6 +40,7 @@ class Line(object):
|
|||
self.raw = l.upper().lstrip()
|
||||
self.imperial = False
|
||||
self.relative = False
|
||||
self.relative_e = False
|
||||
|
||||
if ";" in self.raw:
|
||||
self.raw = self.raw.split(";")[0]
|
||||
|
@ -77,53 +89,55 @@ class Line(object):
|
|||
return ""
|
||||
|
||||
def _get_float(self,which):
|
||||
return float(self.regex.findall(self.raw.split(which)[1])[0])
|
||||
|
||||
try:
|
||||
return float(self.regex.findall(self.raw.split(which)[1])[0])
|
||||
except:
|
||||
return None
|
||||
|
||||
def _parse_coordinates(self):
|
||||
if "X" in self.raw:
|
||||
self._x = self._get_float("X")
|
||||
try:
|
||||
if "X" in self.raw:
|
||||
self._x = self._get_float("X")
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if "Y" in self.raw:
|
||||
self._y = self._get_float("Y")
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if "Z" in self.raw:
|
||||
self._z = self._get_float("Z")
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if "E" in self.raw:
|
||||
self.e = self._get_float("E")
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if "F" in self.raw:
|
||||
self.f = self._get_float("F")
|
||||
except:
|
||||
pass
|
||||
|
||||
if "Y" in self.raw:
|
||||
self._y = self._get_float("Y")
|
||||
|
||||
if "Z" in self.raw:
|
||||
self._z = self._get_float("Z")
|
||||
|
||||
if "E" in self.raw:
|
||||
self.e = self._get_float("E")
|
||||
|
||||
if "F" in self.raw:
|
||||
self.f = self._get_float("F")
|
||||
|
||||
|
||||
def is_move(self):
|
||||
return "G1" in self.raw or "G0" in self.raw
|
||||
return self.command() and ("G1" in self.raw or "G0" in self.raw)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.raw
|
||||
|
||||
class Layer(object):
|
||||
def __init__(self,lines):
|
||||
self.lines = lines
|
||||
|
||||
|
||||
|
||||
class GCode(object):
|
||||
def __init__(self,data):
|
||||
self.lines = [Line(i) for i in data]
|
||||
self._preprocess()
|
||||
|
||||
def _preprocess(self):
|
||||
#checks for G20, G21, G90 and G91, sets imperial and relative flags
|
||||
imperial = False
|
||||
relative = False
|
||||
for line in self.lines:
|
||||
if line.command() == "G20":
|
||||
imperial = True
|
||||
elif line.command() == "G21":
|
||||
imperial = False
|
||||
elif line.command() == "G90":
|
||||
relative = False
|
||||
elif line.command() == "G91":
|
||||
relative = True
|
||||
elif line.is_move():
|
||||
line.imperial = imperial
|
||||
line.relative = relative
|
||||
|
||||
|
||||
def measure(self):
|
||||
xmin = 999999999
|
||||
ymin = 999999999
|
||||
|
@ -132,7 +146,8 @@ class GCode(object):
|
|||
ymax = -999999999
|
||||
zmax = -999999999
|
||||
relative = False
|
||||
|
||||
relative_e = False
|
||||
|
||||
current_x = 0
|
||||
current_y = 0
|
||||
current_z = 0
|
||||
|
@ -147,13 +162,13 @@ class GCode(object):
|
|||
x = line.x
|
||||
y = line.y
|
||||
z = line.z
|
||||
|
||||
|
||||
if line.relative:
|
||||
x = current_x + (x or 0)
|
||||
y = current_y + (y or 0)
|
||||
z = current_z + (z or 0)
|
||||
|
||||
|
||||
|
||||
|
||||
if x and line.e:
|
||||
if x < xmin:
|
||||
xmin = x
|
||||
|
@ -169,22 +184,137 @@ class GCode(object):
|
|||
zmin = z
|
||||
if z > zmax:
|
||||
zmax = z
|
||||
|
||||
|
||||
current_x = x or current_x
|
||||
current_y = y or current_y
|
||||
current_z = z or current_z
|
||||
|
||||
self.xmin = xmin
|
||||
self.ymin = ymin
|
||||
self.zmin = zmin
|
||||
self.xmax = xmax
|
||||
self.ymax = ymax
|
||||
self.zmax = zmax
|
||||
|
||||
self.width = xmax-xmin
|
||||
self.depth = ymax-ymin
|
||||
self.height = zmax-zmin
|
||||
|
||||
return ( (xmin,xmax),(ymin,ymax),(zmin,zmax) )
|
||||
|
||||
|
||||
class GCode(object):
|
||||
def __init__(self,data):
|
||||
self.lines = [Line(i) for i in data]
|
||||
self._preprocess()
|
||||
self._create_layers()
|
||||
|
||||
def _preprocess(self):
|
||||
#checks for G20, G21, G90 and G91, sets imperial and relative flags
|
||||
imperial = False
|
||||
relative = False
|
||||
relative_e = False
|
||||
for line in self.lines:
|
||||
if line.command() == "G20":
|
||||
imperial = True
|
||||
elif line.command() == "G21":
|
||||
imperial = False
|
||||
elif line.command() == "G90":
|
||||
relative = False
|
||||
relative_e = False
|
||||
elif line.command() == "G91":
|
||||
relative = True
|
||||
relative_e = True
|
||||
elif line.command() == "M82":
|
||||
relative_e = False
|
||||
elif line.command() == "M83":
|
||||
relative_e = True
|
||||
elif line.is_move():
|
||||
line.imperial = imperial
|
||||
line.relative = relative
|
||||
line.relative_e = relative_e
|
||||
|
||||
def _create_layers(self):
|
||||
self.layers = []
|
||||
|
||||
prev_z = None
|
||||
cur_z = 0
|
||||
cur_lines = []
|
||||
layer_index = []
|
||||
|
||||
temp_layers = {}
|
||||
for line in self.lines:
|
||||
if line.command() == "G92" and line.z != None:
|
||||
cur_z = line.z
|
||||
elif line.is_move():
|
||||
if line.z != None:
|
||||
if line.relative:
|
||||
cur_z += line.z
|
||||
else:
|
||||
cur_z = line.z
|
||||
|
||||
if cur_z != prev_z:
|
||||
old_lines = temp_layers.pop(prev_z,[])
|
||||
old_lines += cur_lines
|
||||
temp_layers[prev_z] = old_lines
|
||||
|
||||
if not prev_z in layer_index:
|
||||
layer_index.append(prev_z)
|
||||
|
||||
cur_lines = []
|
||||
|
||||
cur_lines.append(line)
|
||||
prev_z = cur_z
|
||||
|
||||
|
||||
old_lines = temp_layers.pop(prev_z,[])
|
||||
old_lines += cur_lines
|
||||
temp_layers[prev_z] = old_lines
|
||||
|
||||
if not prev_z in layer_index:
|
||||
layer_index.append(prev_z)
|
||||
|
||||
layer_index.sort()
|
||||
|
||||
for idx in layer_index:
|
||||
cur_lines = temp_layers[idx]
|
||||
has_movement = False
|
||||
for l in cur_lines:
|
||||
if l.is_move() and l.e != None:
|
||||
has_movement = True
|
||||
break
|
||||
|
||||
if has_movement:
|
||||
self.layers.append(Layer(cur_lines))
|
||||
|
||||
|
||||
def num_layers(self):
|
||||
return len(self.layers)
|
||||
|
||||
|
||||
def measure(self):
|
||||
xmin = 999999999
|
||||
ymin = 999999999
|
||||
zmin = 0
|
||||
xmax = -999999999
|
||||
ymax = -999999999
|
||||
zmax = -999999999
|
||||
|
||||
for l in self.layers:
|
||||
xd,yd,zd = l.measure()
|
||||
if xd[0] < xmin:
|
||||
xmin = xd[0]
|
||||
if xd[1] > xmax:
|
||||
xmax = xd[1]
|
||||
|
||||
if yd[0] < ymin:
|
||||
ymin = yd[0]
|
||||
if yd[1] > ymax:
|
||||
ymax = yd[1]
|
||||
|
||||
if zd[0] < zmin:
|
||||
zmin = zd[0]
|
||||
if zd[1] > zmax:
|
||||
zmax = zd[1]
|
||||
|
||||
self.xmin = xmin
|
||||
self.xmax = xmax
|
||||
self.ymin = ymin
|
||||
self.ymax = ymax
|
||||
self.zmin = zmin
|
||||
self.zmax = zmax
|
||||
self.width = xmax - xmin
|
||||
self.depth = ymax - ymin
|
||||
self.height = zmax - zmin
|
||||
|
||||
def filament_length(self):
|
||||
total_e = 0
|
||||
|
@ -196,7 +326,7 @@ class GCode(object):
|
|||
total_e += cur_e
|
||||
cur_e = line.e
|
||||
elif line.is_move() and line.e:
|
||||
if line.relative:
|
||||
if line.relative_e:
|
||||
cur_e += line.e
|
||||
else:
|
||||
cur_e = line.e
|
||||
|
@ -210,6 +340,8 @@ def main():
|
|||
print "usage: %s filename.gcode" % sys.argv[0]
|
||||
return
|
||||
|
||||
# d = [i.replace("\n","") for i in open(sys.argv[1])]
|
||||
# gcode = GCode(d)
|
||||
gcode = GCode(list(open(sys.argv[1])))
|
||||
|
||||
gcode.measure()
|
||||
|
@ -219,6 +351,8 @@ def main():
|
|||
print "\tY: %0.02f - %0.02f (%0.02f)" % (gcode.ymin,gcode.ymax,gcode.depth)
|
||||
print "\tZ: %0.02f - %0.02f (%0.02f)" % (gcode.zmin,gcode.zmax,gcode.height)
|
||||
print "Filament used: %0.02fmm" % gcode.filament_length()
|
||||
print "Number of layers: %d" % gcode.num_layers()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
82
printcore.py
82
printcore.py
|
@ -20,6 +20,7 @@ from threading import Thread
|
|||
from select import error as SelectError
|
||||
import time, getopt, sys
|
||||
import platform, os
|
||||
from GCodeAnalyzer import GCodeAnalyzer
|
||||
|
||||
def control_ttyhup(port, disable_hup):
|
||||
"""Controls the HUPCL"""
|
||||
|
@ -69,7 +70,11 @@ class printcore():
|
|||
self.print_thread = None
|
||||
if port is not None and baud is not None:
|
||||
self.connect(port, baud)
|
||||
|
||||
self.analyzer = GCodeAnalyzer()
|
||||
self.xy_feedrate = None
|
||||
self.z_feedrate = None
|
||||
self.pronterface = None
|
||||
|
||||
def disconnect(self):
|
||||
"""Disconnects from printer and pauses the print
|
||||
"""
|
||||
|
@ -219,17 +224,69 @@ class printcore():
|
|||
self.print_thread.start()
|
||||
return True
|
||||
|
||||
# run a simple script if it exists, no multithreading
|
||||
def runSmallScript(self, filename):
|
||||
if filename == None: return
|
||||
f = None
|
||||
try:
|
||||
f = open(filename)
|
||||
except:
|
||||
pass
|
||||
|
||||
if f != None:
|
||||
for i in f:
|
||||
l = i.replace("\n", "")
|
||||
l = l[:l.find(";")] #remove comment
|
||||
self.send_now(l)
|
||||
f.close()
|
||||
|
||||
def pause(self):
|
||||
"""Pauses the print, saving the current position.
|
||||
"""
|
||||
if not self.printing: return False
|
||||
self.paused = True
|
||||
self.printing = False
|
||||
self.print_thread.join()
|
||||
|
||||
# try joining the print thread: enclose it in try/except because we might be calling it from the thread itself
|
||||
|
||||
try:
|
||||
self.print_thread.join()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.print_thread = None
|
||||
|
||||
# saves the status
|
||||
self.pauseX = self.analyzer.x-self.analyzer.xOffset;
|
||||
self.pauseY = self.analyzer.y-self.analyzer.yOffset;
|
||||
self.pauseZ = self.analyzer.z-self.analyzer.zOffset;
|
||||
self.pauseE = self.analyzer.e-self.analyzer.eOffset;
|
||||
self.pauseF = self.analyzer.f;
|
||||
self.pauseRelative = self.analyzer.relative;
|
||||
|
||||
|
||||
|
||||
def resume(self):
|
||||
"""Resumes a paused print.
|
||||
"""
|
||||
if not self.paused: return False
|
||||
if self.paused:
|
||||
#restores the status
|
||||
self.send_now("G90") # go to absolute coordinates
|
||||
|
||||
xyFeedString = ""
|
||||
zFeedString = ""
|
||||
if self.xy_feedrate != None: xyFeedString = " F" + str(self.xy_feedrate)
|
||||
if self.z_feedrate != None: zFeedString = " F" + str(self.z_feedrate)
|
||||
|
||||
self.send_now("G1 X" + str(self.pauseX) + " Y" + str(self.pauseY) + xyFeedString)
|
||||
self.send_now("G1 Z" + str(self.pauseZ) + zFeedString)
|
||||
self.send_now("G92 E" + str(self.pauseE))
|
||||
|
||||
if self.pauseRelative: self.send_now("G91") # go back to relative if needed
|
||||
#reset old feed rate
|
||||
self.send_now("G1 F" + str(self.pauseF))
|
||||
|
||||
self.paused = False
|
||||
self.printing = True
|
||||
self.print_thread = Thread(target = self._print)
|
||||
|
@ -287,11 +344,24 @@ class printcore():
|
|||
self.sentlines = {}
|
||||
self.log = []
|
||||
self.sent = []
|
||||
try:
|
||||
self.print_thread.join()
|
||||
except: pass
|
||||
self.print_thread = None
|
||||
if self.endcb:
|
||||
#callback for printing done
|
||||
try: self.endcb()
|
||||
except: pass
|
||||
|
||||
#now only "pause" is implemented as host command
|
||||
def processHostCommand(self, command):
|
||||
command = command.lstrip()
|
||||
if command.startswith(";@pause"):
|
||||
if self.pronterface != None:
|
||||
self.pronterface.pause(None)
|
||||
else:
|
||||
self.pause()
|
||||
|
||||
def _sendnext(self):
|
||||
if not self.printer:
|
||||
return
|
||||
|
@ -312,6 +382,13 @@ class printcore():
|
|||
return
|
||||
if self.printing and self.queueindex < len(self.mainqueue):
|
||||
tline = self.mainqueue[self.queueindex]
|
||||
#check for host command
|
||||
if tline.lstrip().startswith(";@"):
|
||||
#it is a host command: pop it from the list
|
||||
self.mainqueue.pop(self.queueindex)
|
||||
self.processHostCommand(tline)
|
||||
return
|
||||
|
||||
tline = tline.split(";")[0]
|
||||
if len(tline) > 0:
|
||||
self._send(tline, self.lineno, True)
|
||||
|
@ -335,6 +412,7 @@ class printcore():
|
|||
self.sentlines[lineno] = command
|
||||
if self.printer:
|
||||
self.sent.append(command)
|
||||
self.analyzer.Analyze(command) # run the command through the analyzer
|
||||
if self.loud:
|
||||
print "SENT: ", command
|
||||
if self.sendcb:
|
||||
|
|
|
@ -223,7 +223,7 @@ class MainToolbar(wx.BoxSizer):
|
|||
|
||||
root.serialport = wx.ComboBox(root.panel, -1,
|
||||
choices = root.scanserial(),
|
||||
style = wx.CB_DROPDOWN, size = (100, 25))
|
||||
style = wx.CB_DROPDOWN, size = (150, 25))
|
||||
root.serialport.SetToolTip(wx.ToolTip("Select Port Printer is connected to"))
|
||||
root.rescanports()
|
||||
self.Add(root.serialport)
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
236
pronsole.py
236
pronsole.py
|
@ -131,6 +131,14 @@ def estimate_duration(g):
|
|||
#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)))
|
||||
|
||||
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
|
||||
|
||||
class Settings:
|
||||
#def _temperature_alias(self): return {"pla":210, "abs":230, "off":0}
|
||||
#def _temperature_validate(self, v):
|
||||
|
@ -183,15 +191,46 @@ class Settings:
|
|||
def _all_settings(self):
|
||||
return dict([(k, getattr(self, k)) for k in self.__dict__.keys() if not k.startswith("_")])
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
class pronsole(cmd.Cmd):
|
||||
def __init__(self):
|
||||
cmd.Cmd.__init__(self)
|
||||
if not READLINE:
|
||||
self.completekey = None
|
||||
self.status = Status()
|
||||
self.dynamic_temp = False
|
||||
self.p = printcore.printcore()
|
||||
self.p.recvcb = self.recvcb
|
||||
self.recvlisteners = []
|
||||
self.prompt = "PC>"
|
||||
self.in_macro = False
|
||||
self.p.onlinecb = self.online
|
||||
self.f = None
|
||||
self.listing = 0
|
||||
|
@ -213,6 +252,7 @@ class pronsole(cmd.Cmd):
|
|||
self.settings._bedtemp_abs_cb = self.set_temp_preset
|
||||
self.settings._bedtemp_pla_cb = self.set_temp_preset
|
||||
self.monitoring = 0
|
||||
self.silent = False
|
||||
self.helpdict = {}
|
||||
self.helpdict["baudrate"] = _("Communications Speed (default: 115200)")
|
||||
self.helpdict["bedtemp_abs"] = _("Heated Build Platform temp for ABS (default: 110 deg C)")
|
||||
|
@ -227,10 +267,62 @@ class pronsole(cmd.Cmd):
|
|||
self.helpdict["z_feedrate"] = _("Feedrate for Control Panel Moves in Z (default: 200mm/min)")
|
||||
self.helpdict["final_command"] = _("Executable to run when the print is finished")
|
||||
self.commandprefixes='MGT$'
|
||||
self.webrequested = False
|
||||
self.web_config = None
|
||||
self.web_auth_config = None
|
||||
self.promptstrs = {"offline" : "%(bold)suninitialized>%(normal)s ",
|
||||
"fallback" : "%(bold)sPC>%(normal)s ",
|
||||
"macro" : "%(bold)s..>%(normal)s ",
|
||||
"online" : "%(bold)sT:%(extruder_temp_fancy)s %(progress_fancy)s >%(normal)s "}
|
||||
|
||||
def log(self, *msg):
|
||||
print ''.join(str(i) for i in msg)
|
||||
|
||||
def promptf(self):
|
||||
"""A function to generate prompts so that we can do dynamic prompts. """
|
||||
if self.in_macro:
|
||||
promptstr = self.promptstrs["macro"]
|
||||
elif not self.p.online:
|
||||
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))
|
||||
if self.status.extruder_temp_target == 0:
|
||||
specials["extruder_temp_fancy"] = str(int(self.status.extruder_temp))
|
||||
else:
|
||||
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
|
||||
|
||||
def postcmd(self, stop, line):
|
||||
""" A hook we override to generate prompts after
|
||||
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."""
|
||||
if self.p.online and self.dynamic_temp:
|
||||
self.p.send_now("M105")
|
||||
self.prompt = self.promptf()
|
||||
return stop
|
||||
|
||||
def set_temp_preset(self, key, value):
|
||||
if not key.startswith("bed"):
|
||||
self.temps["pla"] = str(self.settings.temperature_pla)
|
||||
|
@ -257,11 +349,11 @@ 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*")
|
||||
|
||||
def online(self):
|
||||
self.log("printer is now online")
|
||||
self.log("\rPrinter is now online")
|
||||
self.write_prompt()
|
||||
|
||||
def write_prompt(self):
|
||||
sys.stdout.write(self.prompt)
|
||||
sys.stdout.write(self.promptf())
|
||||
sys.stdout.flush()
|
||||
|
||||
def help_help(self, l):
|
||||
|
@ -293,7 +385,8 @@ class pronsole(cmd.Cmd):
|
|||
|
||||
def end_macro(self):
|
||||
if self.__dict__.has_key("onecmd"): del self.onecmd # remove override
|
||||
self.prompt = "PC>"
|
||||
self.in_macro = False
|
||||
self.prompt = self.promptf()
|
||||
if self.cur_macro_def!="":
|
||||
self.macros[self.cur_macro_name] = self.cur_macro_def
|
||||
macro = self.compile_macro(self.cur_macro_name, self.cur_macro_def)
|
||||
|
@ -345,7 +438,8 @@ class pronsole(cmd.Cmd):
|
|||
self.cur_macro_name = macro_name
|
||||
self.cur_macro_def = ""
|
||||
self.onecmd = self.hook_macro # override onecmd temporarily
|
||||
self.prompt = "..>"
|
||||
self.in_macro = False
|
||||
self.prompt = self.promptf()
|
||||
|
||||
def delete_macro(self, macro_name):
|
||||
if macro_name in self.macros.keys():
|
||||
|
@ -523,6 +617,7 @@ class pronsole(cmd.Cmd):
|
|||
|
||||
def preloop(self):
|
||||
self.log("Welcome to the printer console! Type \"help\" for a list of available commands.")
|
||||
self.prompt = self.promptf()
|
||||
cmd.Cmd.preloop(self)
|
||||
|
||||
def do_connect(self, l):
|
||||
|
@ -816,11 +911,14 @@ class pronsole(cmd.Cmd):
|
|||
def recvcb(self, l):
|
||||
if "T:" in l:
|
||||
self.tempreadings = l
|
||||
|
||||
self.status.update_tempreading(l)
|
||||
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):
|
||||
self.log(tstring)
|
||||
self.write_prompt()
|
||||
if tstring[:5] == "echo:":
|
||||
tstring = tstring[5:].lstrip()
|
||||
if self.silent == False: print "\r" + tstring.ljust(15)
|
||||
sys.stdout.write(self.promptf())
|
||||
sys.stdout.flush()
|
||||
for i in self.recvlisteners:
|
||||
i(l)
|
||||
|
||||
|
@ -856,11 +954,16 @@ class pronsole(cmd.Cmd):
|
|||
self.log(l.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", ""))
|
||||
|
||||
def do_gettemp(self, l):
|
||||
if "dynamic" in l:
|
||||
self.dynamic_temp = True
|
||||
if self.p.online:
|
||||
self.recvlisteners+=[self.tempcb]
|
||||
self.p.send_now("M105")
|
||||
time.sleep(0.75)
|
||||
self.recvlisteners.remove(self.tempcb)
|
||||
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)
|
||||
|
||||
def help_gettemp(self):
|
||||
self.log("Read the extruder and bed temperature.")
|
||||
|
@ -872,6 +975,10 @@ class pronsole(cmd.Cmd):
|
|||
l = l.replace(i, self.temps[i])
|
||||
f = float(l)
|
||||
if f>=0:
|
||||
if f > 250:
|
||||
print f, " is a high temperature to set your extruder to. Are you sure you want to do that?"
|
||||
if not confirm():
|
||||
return
|
||||
if self.p.online:
|
||||
self.p.send_now("M104 S"+l)
|
||||
self.log("Setting hotend temperature to ", f, " degrees Celsius.")
|
||||
|
@ -1048,9 +1155,22 @@ class pronsole(cmd.Cmd):
|
|||
self.log("reverse -5 - EXTRUDES 5mm of filament at 300mm/min (5mm/s)")
|
||||
|
||||
def do_exit(self, l):
|
||||
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")
|
||||
self.log("Disconnecting from printer...")
|
||||
self.p.disconnect()
|
||||
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
|
||||
self.log("Exiting program. Goodbye!")
|
||||
self.p.disconnect()
|
||||
return True
|
||||
|
||||
def help_exit(self):
|
||||
|
@ -1061,6 +1181,9 @@ class pronsole(cmd.Cmd):
|
|||
if not self.p.online:
|
||||
self.log("printer is not online. Please connect first.")
|
||||
return
|
||||
if not (self.p.printing or self.sdprinting):
|
||||
self.log("Printer not printing. Please print something before monitoring.")
|
||||
return
|
||||
self.log("Monitoring printer, use ^C to interrupt.")
|
||||
if len(l):
|
||||
try:
|
||||
|
@ -1069,22 +1192,28 @@ class pronsole(cmd.Cmd):
|
|||
self.log("Invalid period given.")
|
||||
self.log("Updating values every %f seconds."%(interval,))
|
||||
self.monitoring = 1
|
||||
prev_msg_len = 0
|
||||
try:
|
||||
while(1):
|
||||
while True:
|
||||
self.p.send_now("M105")
|
||||
if(self.sdprinting):
|
||||
self.p.send_now("M27")
|
||||
time.sleep(interval)
|
||||
#self.log((self.tempreadings.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", "")))
|
||||
if(self.p.printing):
|
||||
self.log("print progress: ", 100*float(self.p.queueindex)/len(self.p.mainqueue), "%")
|
||||
|
||||
if(self.sdprinting):
|
||||
self.log("SD print progress: ", self.percentdone, "%")
|
||||
|
||||
except:
|
||||
self.log("Done monitoring.")
|
||||
pass
|
||||
#print (self.tempreadings.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", ""))
|
||||
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) + "%"
|
||||
if self.silent == False:
|
||||
sys.stdout.write("\r" + prev_msg.ljust(prev_msg_len))
|
||||
sys.stdout.flush()
|
||||
prev_msg_len = len(prev_msg)
|
||||
except KeyboardInterrupt:
|
||||
if self.silent == False: print "Done monitoring."
|
||||
self.monitoring = 0
|
||||
|
||||
def help_monitor(self):
|
||||
|
@ -1190,6 +1319,69 @@ class pronsole(cmd.Cmd):
|
|||
self.onecmd(a)
|
||||
self.processing_args = False
|
||||
|
||||
|
||||
# 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 ""
|
||||
should_exit = self.do_exit("")
|
||||
if should_exit:
|
||||
exit()
|
||||
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
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
interp = pronsole()
|
||||
|
|
|
@ -85,7 +85,7 @@ class Tee(object):
|
|||
class PronterWindow(MainWindow, pronsole.pronsole):
|
||||
def __init__(self, filename = None, size = winsize):
|
||||
pronsole.pronsole.__init__(self)
|
||||
self.settings.build_dimensions = '200x200x100+0+0+0' #default build dimensions are 200x200x100 with 0, 0, 0 in the corner of the bed
|
||||
self.settings.build_dimensions = '200x200x100+0+0+0+0+0+0' #default build dimensions are 200x200x100 with 0, 0, 0 in the corner of the bed
|
||||
self.settings.last_bed_temperature = 0.0
|
||||
self.settings.last_file_path = ""
|
||||
self.settings.last_temperature = 0.0
|
||||
|
@ -93,7 +93,11 @@ class PronterWindow(MainWindow, pronsole.pronsole):
|
|||
self.settings.preview_grid_step1 = 10.
|
||||
self.settings.preview_grid_step2 = 50.
|
||||
self.settings.bgcolor = "#FFFFFF"
|
||||
self.helpdict["build_dimensions"] = _("Dimensions of Build Platform\n & optional offset of origin\n\nExamples:\n XXXxYYY\n XXX,YYY,ZZZ\n XXXxYYYxZZZ+OffX+OffY+OffZ")
|
||||
|
||||
self.pauseScript = "pause.gcode"
|
||||
self.endScript = "end.gcode"
|
||||
|
||||
self.helpdict["build_dimensions"] = _("Dimensions of Build Platform\n & optional offset of origin\n & optional switch position\n\nExamples:\n XXXxYYY\n XXX,YYY,ZZZ\n XXXxYYYxZZZ+OffX+OffY+OffZ\nXXXxYYYxZZZ+OffX+OffY+OffZ+HomeX+HomeY+HomeZ")
|
||||
self.helpdict["last_bed_temperature"] = _("Last Set Temperature for the Heated Print Bed")
|
||||
self.helpdict["last_file_path"] = _("Folder of last opened file")
|
||||
self.helpdict["last_temperature"] = _("Last Temperature of the Hot End")
|
||||
|
@ -128,6 +132,30 @@ class PronterWindow(MainWindow, pronsole.pronsole):
|
|||
self.btndict = {}
|
||||
self.parse_cmdline(sys.argv[1:])
|
||||
self.build_dimensions_list = self.get_build_dimensions(self.settings.build_dimensions)
|
||||
|
||||
#initialize the code analyzer with the correct sizes. There must be a more general way to do so
|
||||
|
||||
# minimum = offset
|
||||
self.p.analyzer.minX = self.build_dimensions_list[3]
|
||||
self.p.analyzer.minY = self.build_dimensions_list[4]
|
||||
self.p.analyzer.minZ = self.build_dimensions_list[5]
|
||||
|
||||
#max = offset + bedsize
|
||||
self.p.analyzer.maxX = self.build_dimensions_list[3] + self.build_dimensions_list[0]
|
||||
self.p.analyzer.maxY = self.build_dimensions_list[4] + self.build_dimensions_list[1]
|
||||
self.p.analyzer.maxZ = self.build_dimensions_list[5] + self.build_dimensions_list[2]
|
||||
|
||||
self.p.analyzer.homeX = self.build_dimensions_list[6]
|
||||
self.p.analyzer.homeY = self.build_dimensions_list[7]
|
||||
self.p.analyzer.homeZ = self.build_dimensions_list[8]
|
||||
|
||||
#set feedrates in printcore for pause/resume
|
||||
self.p.xy_feedrate = self.settings.xy_feedrate
|
||||
self.p.z_feedrate = self.settings.z_feedrate
|
||||
|
||||
#make printcore aware of me
|
||||
self.p.pronterface = self
|
||||
|
||||
self.panel.SetBackgroundColour(self.settings.bgcolor)
|
||||
customdict = {}
|
||||
try:
|
||||
|
@ -183,6 +211,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
|
|||
wx.CallAfter(self.pausebtn.Disable)
|
||||
wx.CallAfter(self.printbtn.SetLabel, _("Print"))
|
||||
|
||||
self.p.runSmallScript(self.endScript)
|
||||
|
||||
param = self.settings.final_command
|
||||
if not param:
|
||||
return
|
||||
|
@ -268,16 +298,16 @@ class PronterWindow(MainWindow, pronsole.pronsole):
|
|||
if f>0:
|
||||
wx.CallAfter(self.btemp.SetValue, str(f))
|
||||
self.set("last_bed_temperature", str(f))
|
||||
wx.CallAfter(self.setboff.SetBackgroundColour, "")
|
||||
wx.CallAfter(self.setboff.SetForegroundColour, "")
|
||||
wx.CallAfter(self.setboff.SetBackgroundColour, None)
|
||||
wx.CallAfter(self.setboff.SetForegroundColour, None)
|
||||
wx.CallAfter(self.setbbtn.SetBackgroundColour, "#FFAA66")
|
||||
wx.CallAfter(self.setbbtn.SetForegroundColour, "#660000")
|
||||
wx.CallAfter(self.btemp.SetBackgroundColour, "#FFDABB")
|
||||
else:
|
||||
wx.CallAfter(self.setboff.SetBackgroundColour, "#0044CC")
|
||||
wx.CallAfter(self.setboff.SetForegroundColour, "white")
|
||||
wx.CallAfter(self.setbbtn.SetBackgroundColour, "")
|
||||
wx.CallAfter(self.setbbtn.SetForegroundColour, "")
|
||||
wx.CallAfter(self.setbbtn.SetBackgroundColour, None)
|
||||
wx.CallAfter(self.setbbtn.SetForegroundColour, None)
|
||||
wx.CallAfter(self.btemp.SetBackgroundColour, "white")
|
||||
wx.CallAfter(self.btemp.Refresh)
|
||||
|
||||
|
@ -287,16 +317,16 @@ class PronterWindow(MainWindow, pronsole.pronsole):
|
|||
if f > 0:
|
||||
wx.CallAfter(self.htemp.SetValue, str(f))
|
||||
self.set("last_temperature", str(f))
|
||||
wx.CallAfter(self.settoff.SetBackgroundColour, "")
|
||||
wx.CallAfter(self.settoff.SetForegroundColour, "")
|
||||
wx.CallAfter(self.settoff.SetBackgroundColour, None)
|
||||
wx.CallAfter(self.settoff.SetForegroundColour, None)
|
||||
wx.CallAfter(self.settbtn.SetBackgroundColour, "#FFAA66")
|
||||
wx.CallAfter(self.settbtn.SetForegroundColour, "#660000")
|
||||
wx.CallAfter(self.htemp.SetBackgroundColour, "#FFDABB")
|
||||
else:
|
||||
wx.CallAfter(self.settoff.SetBackgroundColour, "#0044CC")
|
||||
wx.CallAfter(self.settoff.SetForegroundColour, "white")
|
||||
wx.CallAfter(self.settbtn.SetBackgroundColour, "")
|
||||
wx.CallAfter(self.settbtn.SetForegroundColour, "")
|
||||
wx.CallAfter(self.settbtn.SetBackgroundColour, None)
|
||||
wx.CallAfter(self.settbtn.SetForegroundColour, None)
|
||||
wx.CallAfter(self.htemp.SetBackgroundColour, "white")
|
||||
wx.CallAfter(self.htemp.Refresh)
|
||||
|
||||
|
@ -1336,7 +1366,9 @@ class PronterWindow(MainWindow, pronsole.pronsole):
|
|||
#print "Not printing, cannot pause."
|
||||
return
|
||||
self.p.pause()
|
||||
self.p.runSmallScript(self.pauseScript)
|
||||
self.paused = True
|
||||
#self.p.runSmallScript(self.pauseScript)
|
||||
self.extra_print_time += int(time.time() - self.starttime)
|
||||
wx.CallAfter(self.pausebtn.SetLabel, _("Resume"))
|
||||
else:
|
||||
|
@ -1475,9 +1507,12 @@ class PronterWindow(MainWindow, pronsole.pronsole):
|
|||
"[^\d+-]*(\d+)?" + # Z build size
|
||||
"[^\d+-]*([+-]\d+)?" + # X corner coordinate
|
||||
"[^\d+-]*([+-]\d+)?" + # Y corner coordinate
|
||||
"[^\d+-]*([+-]\d+)?" # Z corner coordinate
|
||||
"[^\d+-]*([+-]\d+)?" + # Z corner coordinate
|
||||
"[^\d+-]*([+-]\d+)?" + # X endstop
|
||||
"[^\d+-]*([+-]\d+)?" + # Y endstop
|
||||
"[^\d+-]*([+-]\d+)?" # Z endstop
|
||||
,bdim).groups()
|
||||
defaults = [200, 200, 100, 0, 0, 0]
|
||||
defaults = [200, 200, 100, 0, 0, 0, 0, 0, 0]
|
||||
bdl_float = [float(value) if value else defaults[i] for i, value in enumerate(bdl)]
|
||||
return bdl_float
|
||||
|
||||
|
|
Loading…
Reference in New Issue