Merge branch 'devel' into sdcard

Conflicts:
	octoprint/server.py
	octoprint/settings.py
	octoprint/static/js/ui.js
	octoprint/util/comm.py
master
Gina Häußge 2013-05-23 22:53:34 +02:00
commit 16f5e54bd7
8 changed files with 245 additions and 72 deletions

View File

@ -237,7 +237,8 @@ class Printer():
self._setProgressData(None, None, None, None) self._setProgressData(None, None, None, None)
# mark print as failure # mark print as failure
self._gcodeManager.printFailed(self._filename) if self._filename is not None:
self._gcodeManager.printFailed(self._filename)
#~~ state monitoring #~~ state monitoring
@ -578,7 +579,7 @@ class GcodeLoader(threading.Thread):
def run(self): def run(self):
#Send an initial M110 to reset the line counter to zero. #Send an initial M110 to reset the line counter to zero.
prevLineType = lineType = "CUSTOM" prevLineType = lineType = "CUSTOM"
gcodeList = ["M110"] gcodeList = ["M110 N0"]
filesize = os.stat(self._filename).st_size filesize = os.stat(self._filename).st_size
with open(self._filename, "r") as file: with open(self._filename, "r") as file:
for line in file: for line in file:

View File

@ -404,6 +404,8 @@ def getSettings():
"feature": { "feature": {
"gcodeViewer": s.getBoolean(["feature", "gCodeVisualizer"]), "gcodeViewer": s.getBoolean(["feature", "gCodeVisualizer"]),
"waitForStart": s.getBoolean(["feature", "waitForStartOnConnect"]), "waitForStart": s.getBoolean(["feature", "waitForStartOnConnect"]),
"alwaysSendChecksum": s.getBoolean(["feature", "alwaysSendChecksum"]),
"resetLineNumbersWithPrefixedN": s.getBoolean(["feature", "resetLineNumbersWithPrefixedN"]),
"sdSupport": s.getBoolean(["feature", "sdSupport"]) "sdSupport": s.getBoolean(["feature", "sdSupport"])
}, },
"folder": { "folder": {
@ -448,6 +450,8 @@ def setSettings():
if "feature" in data.keys(): if "feature" in data.keys():
if "gcodeViewer" in data["feature"].keys(): s.setBoolean(["feature", "gCodeVisualizer"], data["feature"]["gcodeViewer"]) if "gcodeViewer" in data["feature"].keys(): s.setBoolean(["feature", "gCodeVisualizer"], data["feature"]["gcodeViewer"])
if "waitForStart" in data["feature"].keys(): s.setBoolean(["feature", "waitForStartOnConnect"], data["feature"]["waitForStart"]) if "waitForStart" in data["feature"].keys(): s.setBoolean(["feature", "waitForStartOnConnect"], data["feature"]["waitForStart"])
if "alwaysSendChecksum" in data["feature"].keys(): s.setBoolean(["feature", "alwaysSendChecksum"], data["feature"]["alwaysSendChecksum"])
if "resetLineNumbersWithPrefixedN" in data["feature"].keys(): s.setBoolean(["feature", "resetLineNumbersWithPrefixedN"], data["feature"]["resetLineNumbersWithPrefixedN"])
if "sdSupport" in data["feature"].keys(): s.setBoolean(["feature", "sdSupport"], data["feature"]["sdSupport"]) if "sdSupport" in data["feature"].keys(): s.setBoolean(["feature", "sdSupport"], data["feature"]["sdSupport"])
if "folder" in data.keys(): if "folder" in data.keys():

View File

@ -40,6 +40,9 @@ default_settings = {
"feature": { "feature": {
"gCodeVisualizer": True, "gCodeVisualizer": True,
"waitForStartOnConnect": False, "waitForStartOnConnect": False,
"waitForWaitOnConnect": False,
"alwaysSendChecksum": False,
"resetLineNumbersWithPrefixedN": False,
"sdSupport": False "sdSupport": False
}, },
"folder": { "folder": {

View File

@ -1299,6 +1299,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.feature_gcodeViewer = ko.observable(undefined); self.feature_gcodeViewer = ko.observable(undefined);
self.feature_waitForStart = ko.observable(undefined); self.feature_waitForStart = ko.observable(undefined);
self.feature_alwaysSendChecksum = ko.observable(undefined);
self.feature_resetLineNumbersWithPrefixedN = ko.observable(undefined);
self.feature_sdSupport = ko.observable(undefined); self.feature_sdSupport = ko.observable(undefined);
self.folder_uploads = ko.observable(undefined); self.folder_uploads = ko.observable(undefined);
@ -1344,6 +1346,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.feature_gcodeViewer(response.feature.gcodeViewer); self.feature_gcodeViewer(response.feature.gcodeViewer);
self.feature_waitForStart(response.feature.waitForStart); self.feature_waitForStart(response.feature.waitForStart);
self.feature_alwaysSendChecksum(response.feature.alwaysSendChecksum);
self.feature_resetLineNumbersWithPrefixedN(response.feature.resetLineNumbersWithPrefixedN);
self.feature_sdSupport(response.feature.sdSupport); self.feature_sdSupport(response.feature.sdSupport);
self.folder_uploads(response.folder.uploads); self.folder_uploads(response.folder.uploads);
@ -1378,6 +1382,9 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
"feature": { "feature": {
"gcodeViewer": self.feature_gcodeViewer(), "gcodeViewer": self.feature_gcodeViewer(),
"waitForStart": self.feature_waitForStart(), "waitForStart": self.feature_waitForStart(),
"alwaysSendChecksum": self.feature_alwaysSendChecksum(),
"resetLineNumbersWithPrefixedN": self.feature_resetLineNumbersWithPrefixedN(),
"waitForStart": self.feature_waitForStart(),
"sdSupport": self.feature_sdSupport() "sdSupport": self.feature_sdSupport()
}, },
"folder": { "folder": {

View File

@ -562,7 +562,7 @@
{% include 'settings.jinja2' %} {% include 'settings.jinja2' %}
{% include 'dialogs.jinja2' %} {% include 'dialogs.jinja2' %}
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/modernizr.custom.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/modernizr.custom.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/underscore.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/underscore.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/knockout.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/knockout.js') }}"></script>

View File

@ -103,7 +103,21 @@
<div class="control-group"> <div class="control-group">
<div class="controls"> <div class="controls">
<label class="checkbox"> <label class="checkbox">
<input type="checkbox" data-bind="checked: feature_waitForStart" id="settings-featureWaitForStart"> Wait for start on connect <input type="checkbox" data-bind="checked: feature_waitForStart" id="settings-featureWaitForStart"> Wait for <code>start</code> on connect
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_alwaysSendChecksum" id="settings-featureAlwaysSendChecksum"> Send a checksum with <strong>every</strong> command <span class="label">Repetier</span>
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_resetLineNumbersWithPrefixedN" id="settings-resetLineNumbersWithPrefixedN"> Send M110 commands with target line number as N-prefix <span class="label">Repetier</span>
</label> </label>
</div> </div>
</div> </div>

View File

@ -73,6 +73,11 @@ class VirtualPrinter():
self._writingToSd = False self._writingToSd = False
self._newSdFilePos = None self._newSdFilePos = None
self.currentLine = 0
waitThread = threading.Thread(target=self._sendWaitAfterTimeout)
waitThread.start()
def write(self, data): def write(self, data):
if self.readList is None: if self.readList is None:
return return
@ -96,6 +101,7 @@ class VirtualPrinter():
pass pass
if 'M105' in data: if 'M105' in data:
# send simulated temperature data
self.readList.append("ok T:%.2f /%.2f B:%.2f /%.2f @:64\n" % (self.temp, self.targetTemp, self.bedTemp, self.bedTargetTemp)) self.readList.append("ok T:%.2f /%.2f B:%.2f /%.2f @:64\n" % (self.temp, self.targetTemp, self.bedTemp, self.bedTargetTemp))
elif 'M20' in data: elif 'M20' in data:
self._listSd() self._listSd()
@ -119,9 +125,20 @@ class VirtualPrinter():
elif 'M30' in data: elif 'M30' in data:
filename = data.split(None, 1)[1].strip() filename = data.split(None, 1)[1].strip()
self._deleteSdFile(filename) self._deleteSdFile(filename)
elif "M110" in data:
# reset current line
self.currentLine = int(re.search('N([0-9]+)', data).group(1))
self.readList.append("ok\n")
elif self.currentLine == 100:
# simulate a resend at line 100 of the last 5 lines
self.readList.append("Error: Line Number is not Last Line Number\n")
self.readList.append("rs %d\n" % (self.currentLine - 5))
elif len(data.strip()) > 0: elif len(data.strip()) > 0:
self.readList.append("ok\n") self.readList.append("ok\n")
if "*" in data:
self.currentLine += 1
def _listSd(self): def _listSd(self):
self.readList.append("Begin file list") self.readList.append("Begin file list")
for osFile in os.listdir(self._virtualSd): for osFile in os.listdir(self._virtualSd):
@ -244,6 +261,10 @@ class VirtualPrinter():
def close(self): def close(self):
self.readList = None self.readList = None
def _sendWaitAfterTimeout(self, timeout=5):
time.sleep(timeout)
self.readList.append("wait")
class MachineComPrintCallback(object): class MachineComPrintCallback(object):
def mcLog(self, message): def mcLog(self, message):
pass pass
@ -321,7 +342,15 @@ class MachineCom(object):
self._heatupWaitStartTime = 0 self._heatupWaitStartTime = 0
self._heatupWaitTimeLost = 0.0 self._heatupWaitTimeLost = 0.0
self._printStartTime = None self._printStartTime = None
self._alwaysSendChecksum = settings().getBoolean(["feature", "alwaysSendChecksum"])
self._currentLine = 1
self._resendDelta = None
self._lastLines = []
self._sendNextLock = threading.Lock()
self._sendingLock = threading.Lock()
self.thread = threading.Thread(target=self._monitor) self.thread = threading.Thread(target=self._monitor)
self.thread.daemon = True self.thread.daemon = True
self.thread.start() self.thread.start()
@ -527,7 +556,13 @@ class MachineCom(object):
if re.match('Error:[0-9]\n', line): if re.match('Error:[0-9]\n', line):
line = line.rstrip() + self._readline() line = line.rstrip() + self._readline()
#Skip the communication errors, as those get corrected. #Skip the communication errors, as those get corrected.
if 'checksum mismatch' in line or 'Line Number is not Last Line Number' in line or 'No Line Number with checksum' in line or 'No Checksum with line number' in line: if 'checksum mismatch' in line \
or 'Wrong checksum' in line \
or 'Line Number is not Last Line Number' in line \
or 'expected line' in line \
or 'No Line Number with checksum' in line \
or 'No Checksum with line number' in line \
or 'Missing checksum' in line:
pass pass
elif not self.isError(): elif not self.isError():
self._errorValue = line[6:] self._errorValue = line[6:]
@ -541,10 +576,16 @@ class MachineCom(object):
##~~ Temperature processing ##~~ Temperature processing
if ' T:' in line or line.startswith('T:'): if ' T:' in line or line.startswith('T:'):
self._temp = float(re.search("-?[0-9\.]*", line.split('T:')[1]).group(0)) try:
if ' B:' in line: self._temp = float(re.search("-?[0-9\.]*", line.split('T:')[1]).group(0))
self._bedTemp = float(re.search("-?[0-9\.]*", line.split(' B:')[1]).group(0)) if ' B:' in line:
self._callback.mcTempUpdate(self._temp, self._bedTemp, self._targetTemp, self._bedTargetTemp) self._bedTemp = float(re.search("-?[0-9\.]*", line.split(' B:')[1]).group(0))
self._callback.mcTempUpdate(self._temp, self._bedTemp, self._targetTemp, self._bedTargetTemp)
except ValueError:
# catch conversion issues, we'll rather just not get the temperature update instead of killing the connection
pass
#If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate. #If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
if not 'ok' in line and self._heatupWaitStartTime != 0: if not 'ok' in line and self._heatupWaitStartTime != 0:
t = time.time() t = time.time()
@ -580,9 +621,10 @@ class MachineCom(object):
self._callback.mcSdPrintingDone() self._callback.mcSdPrintingDone()
##~~ Message handling ##~~ Message handling
elif line.strip() != '' and line.strip() != 'ok' and not line.startswith('Resend:') and line != 'echo:Unknown command:""\n' and self.isOperational(): elif line.strip() != '' and line.strip() != 'ok' and not line.startswith("wait") and not line.startswith('Resend:') and line != 'echo:Unknown command:""\n' and self.isOperational():
self._callback.mcMessage(line) self._callback.mcMessage(line)
### Baudrate detection
if self._state == self.STATE_DETECT_BAUDRATE: if self._state == self.STATE_DETECT_BAUDRATE:
if line == '' or time.time() > timeout: if line == '' or time.time() > timeout:
if len(self._baudrateDetectList) < 1: if len(self._baudrateDetectList) < 1:
@ -620,24 +662,38 @@ class MachineCom(object):
self._changeState(self.STATE_OPERATIONAL) self._changeState(self.STATE_OPERATIONAL)
else: else:
self._testingBaudrate = False self._testingBaudrate = False
### Connection attempt
elif self._state == self.STATE_CONNECTING: elif self._state == self.STATE_CONNECTING:
if line == '' and startSeen: if (line == "" or "wait" in line) and startSeen:
self._sendCommand("M105") self._sendCommand("M105")
elif 'start' in line: elif "start" in line:
startSeen = True startSeen = True
elif 'ok' in line and startSeen: elif "ok" in line and startSeen:
self._changeState(self.STATE_OPERATIONAL) self._changeState(self.STATE_OPERATIONAL)
if settings().get(["feature", "sdSupport"]): if settings().get(["feature", "sdSupport"]):
self._sendCommand("M20") self._sendCommand("M20")
elif time.time() > timeout: elif time.time() > timeout:
self.close() self.close()
### Operational
elif self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PAUSED: elif self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PAUSED:
#Request the temperature on comm timeout (every 5 seconds) when we are not printing. #Request the temperature on comm timeout (every 5 seconds) when we are not printing.
if line == '': if line == "" or "wait" in line:
self._sendCommand("M105") if self._resendDelta is not None:
self._resendNextCommand()
elif not self._commandQueue.empty():
self._sendCommand(self._commandQueue.get())
else:
self._sendCommand("M105")
tempRequestTimeout = time.time() + 5 tempRequestTimeout = time.time() + 5
# resend -> start resend procedure from requested line
elif "resend" in line.lower() or "rs" in line:
self._handleResendRequest(line)
### Printing
elif self._state == self.STATE_PRINTING: elif self._state == self.STATE_PRINTING:
if line == '' and time.time() > timeout: if line == "" and time.time() > timeout:
self._log("Communication timeout during printing, forcing a line") self._log("Communication timeout during printing, forcing a line")
line = 'ok' line = 'ok'
@ -656,18 +712,33 @@ class MachineCom(object):
else: else:
if 'ok' in line: if 'ok' in line:
timeout = time.time() + 5 timeout = time.time() + 5
if not self._commandQueue.empty(): if self._resendDelta is not None:
self._resendNextCommand()
elif not self._commandQueue.empty():
self._sendCommand(self._commandQueue.get()) self._sendCommand(self._commandQueue.get())
else: else:
self._sendNext() self._sendNext()
elif "resend" in line.lower() or "rs" in line: elif "resend" in line.lower() or "rs" in line:
try: self._handleResendRequest(line)
self._gcodePos = int(line.replace("N:"," ").replace("N"," ").replace(":"," ").split()[-1])
except:
if "rs" in line:
self._gcodePos = int(line.split()[1])
self._log("Connection closed, closing down monitor") self._log("Connection closed, closing down monitor")
def _handleResendRequest(self, line):
lineToResend = None
try:
lineToResend = int(line.replace("N:"," ").replace("N"," ").replace(":"," ").split()[-1])
except:
if "rs" in line:
lineToResend = int(line.split()[1])
if lineToResend is not None:
self._resendDelta = self._currentLine - lineToResend
if self._resendDelta > len(self._lastLines):
self._errorValue = "Printer requested line %d but history is only available up to line %d" % (lineToResend, self._currentLine - len(self._lastLines))
self._changeState(self.STATE_ERROR)
self._logger.warn(self._errorValue)
else:
self._resendNextCommand()
def _log(self, message): def _log(self, message):
self._callback.mcLog(message) self._callback.mcLog(message)
self._serialLogger.debug(message) self._serialLogger.debug(message)
@ -711,23 +782,91 @@ class MachineCom(object):
def __del__(self): def __del__(self):
self.close() self.close()
def _sendCommand(self, cmd): def _resendNextCommand(self):
if self._serial is None: # Make sure we are only handling one sending job at a time
return with self._sendingLock:
if 'M109' in cmd or 'M190' in cmd: self._logger.debug("Resending line %d, delta is %d, history log is %s items strong" % (self._currentLine - self._resendDelta, self._resendDelta, len(self._lastLines)))
self._heatupWaitStartTime = time.time() cmd = self._lastLines[-self._resendDelta]
if 'M104' in cmd or 'M109' in cmd: lineNumber = self._currentLine - self._resendDelta
try:
self._targetTemp = float(re.search('S([0-9]+)', cmd).group(1)) self._doSendWithChecksum(cmd, lineNumber)
except:
pass self._resendDelta -= 1
if 'M140' in cmd or 'M190' in cmd: if self._resendDelta <= 0:
try: self._resendDelta = None
self._bedTargetTemp = float(re.search('S([0-9]+)', cmd).group(1))
except: def _sendCommand(self, cmd, sendChecksum=False):
pass # Make sure we are only handling one sending job at a time
self._log('Send: %s' % (cmd)) with self._sendingLock:
if self._serial is None:
return
if 'M109' in cmd or 'M190' in cmd:
self._heatupWaitStartTime = time.time()
if 'M104' in cmd or 'M109' in cmd:
try:
self._targetTemp = float(re.search('S([0-9]+)', cmd).group(1))
except:
pass
if 'M140' in cmd or 'M190' in cmd:
try:
self._bedTargetTemp = float(re.search('S([0-9]+)', cmd).group(1))
except:
pass
if "M110" in cmd:
newLineNumber = None
if " N" in cmd:
try:
newLineNumber = int(re.search("N([0-9]+)", cmd).group(1))
except:
pass
else:
newLineNumber = 0
if settings().getBoolean(["feature", "resetLineNumbersWithPrefixedN"]) and newLineNumber is not None:
# let's rewrite the M110 command to fit repetier syntax
self._addToLastLines(cmd)
self._doSendWithChecksum("M110", newLineNumber)
else:
self._doSend(cmd, sendChecksum)
if newLineNumber is not None:
self._currentLine = newLineNumber + 1
# after a reset of the line number we have no way to determine what line exactly the printer now wants
self._lastLines = []
self._resendDelta = None
else:
self._doSend(cmd, sendChecksum)
def _addToLastLines(self, cmd):
self._lastLines.append(cmd)
if len(self._lastLines) > 50:
self._lastLines = self._lastLines[-50:] # only keep the last 50 lines in memory
self._logger.debug("Got %d lines of history in memory" % len(self._lastLines))
def _doSend(self, cmd, sendChecksum=False):
if sendChecksum or self._alwaysSendChecksum:
if self._alwaysSendChecksum:
lineNumber = self._currentLine
else:
lineNumber = self._gcodePos
self._addToLastLines(cmd)
self._currentLine += 1
self._doSendWithChecksum(cmd, lineNumber)
else:
self._doSendWithoutChecksum(cmd)
def _doSendWithChecksum(self, cmd, lineNumber):
self._logger.debug("Sending cmd '%s' with lineNumber %r" % (cmd, lineNumber))
checksum = reduce(lambda x,y:x^y, map(ord, "N%d%s" % (lineNumber, cmd)))
commandToSend = "N%d%s*%d" % (lineNumber, cmd, checksum)
self._doSendWithoutChecksum(commandToSend)
def _doSendWithoutChecksum(self, cmd):
self._log("Send: %s" % cmd)
try: try:
self._serial.write(cmd + '\n') self._serial.write(cmd + '\n')
except serial.SerialTimeoutException: except serial.SerialTimeoutException:
@ -742,34 +881,34 @@ class MachineCom(object):
self._log("Unexpected error while writing serial port: %s" % (getExceptionString())) self._log("Unexpected error while writing serial port: %s" % (getExceptionString()))
self._errorValue = getExceptionString() self._errorValue = getExceptionString()
self.close(True) self.close(True)
def _sendNext(self): def _sendNext(self):
if self._gcodePos >= len(self._gcodeList): with self._sendNextLock:
self._changeState(self.STATE_OPERATIONAL) if self._gcodePos >= len(self._gcodeList):
return self._changeState(self.STATE_OPERATIONAL)
if self._gcodePos == 100: return
self._printStartTime = time.time() if self._gcodePos == 100:
line = self._gcodeList[self._gcodePos] self._printStartTime100 = time.time()
if type(line) is tuple: line = self._gcodeList[self._gcodePos]
self._printSection = line[1] if type(line) is tuple:
line = line[0] self._printSection = line[1]
try: line = line[0]
if line == 'M0' or line == 'M1': try:
self.setPause(True) if line == 'M0' or line == 'M1':
line = 'M105' #Don't send the M0 or M1 to the machine, as M0 and M1 are handled as an LCD menu pause. self.setPause(True)
if self._printSection in self._feedRateModifier: line = 'M105' #Don't send the M0 or M1 to the machine, as M0 and M1 are handled as an LCD menu pause.
line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self._feedRateModifier[self._printSection])), line) if self._printSection in self._feedRateModifier:
if ('G0' in line or 'G1' in line) and 'Z' in line: line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self._feedRateModifier[self._printSection])), line)
z = float(re.search('Z([0-9\.]*)', line).group(1)) if ('G0' in line or 'G1' in line) and 'Z' in line:
if self._currentZ != z: z = float(re.search('Z([0-9\.]*)', line).group(1))
self._currentZ = z if self._currentZ != z:
self._callback.mcZChange(z) self._currentZ = z
except: self._callback.mcZChange(z)
self._log("Unexpected error: %s" % (getExceptionString())) except:
checksum = reduce(lambda x,y:x^y, map(ord, "N%d%s" % (self._gcodePos, line))) self._log("Unexpected error: %s" % (getExceptionString()))
self._sendCommand("N%d%s*%d" % (self._gcodePos, line, checksum)) self._sendCommand(line, True)
self._gcodePos += 1 self._gcodePos += 1
self._callback.mcProgress() self._callback.mcProgress(self._gcodePos)
def sendCommand(self, cmd): def sendCommand(self, cmd):
cmd = cmd.encode('ascii', 'replace') cmd = cmd.encode('ascii', 'replace')
@ -788,8 +927,7 @@ class MachineCom(object):
self._printSection = 'CUSTOM' self._printSection = 'CUSTOM'
self._changeState(self.STATE_PRINTING) self._changeState(self.STATE_PRINTING)
self._printStartTime = time.time() self._printStartTime = time.time()
for i in xrange(0, 6): self._sendNext()
self._sendNext()
def selectSdFile(self, filename): def selectSdFile(self, filename):
if not self.isOperational() or self.isPrinting(): if not self.isOperational() or self.isPrinting():

View File

@ -72,6 +72,8 @@ class gcode(object):
pathType = 'CUSTOM'; pathType = 'CUSTOM';
startCodeDone = False startCodeDone = False
currentLayer = [] currentLayer = []
unknownGcodes={}
unknownMcodes={}
currentPath = gcodePath('move', pathType, layerThickness, pos.copy()) currentPath = gcodePath('move', pathType, layerThickness, pos.copy())
currentPath.list[0].e = totalExtrusion currentPath.list[0].e = totalExtrusion
currentPath.list[0].extrudeAmountMultiply = extrudeAmountMultiply currentPath.list[0].extrudeAmountMultiply = extrudeAmountMultiply
@ -220,7 +222,9 @@ class gcode(object):
if z is not None: if z is not None:
posOffset.z = pos.z - z posOffset.z = pos.z - z
else: else:
print "Unknown G code:" + str(G) if G not in unknownGcodes:
print "Unknown G code:" + str(G)
unknownGcodes[G] = True
else: else:
M = self.getCodeInt(line, 'M') M = self.getCodeInt(line, 'M')
if M is not None: if M is not None:
@ -267,7 +271,9 @@ class gcode(object):
if s != None: if s != None:
extrudeAmountMultiply = s / 100.0 extrudeAmountMultiply = s / 100.0
else: else:
print "Unknown M code:" + str(M) if M not in unknownMcodes:
print "Unknown M code:" + str(M)
unknownMcodes[M] = True
self.layerList.append(currentLayer) self.layerList.append(currentLayer)
self.extrusionAmount = maxExtrusion self.extrusionAmount = maxExtrusion
self.totalMoveTimeMinute = totalMoveTimeMinute self.totalMoveTimeMinute = totalMoveTimeMinute