diff --git a/octoprint/server.py b/octoprint/server.py
index 9a342da..d61d8b5 100644
--- a/octoprint/server.py
+++ b/octoprint/server.py
@@ -359,7 +359,8 @@ def getSettings():
},
"feature": {
"gcodeViewer": s.getBoolean(["feature", "gCodeVisualizer"]),
- "waitForStart": s.getBoolean(["feature", "waitForStartOnConnect"])
+ "waitForStart": s.getBoolean(["feature", "waitForStartOnConnect"]),
+ "alwaysSendChecksum": s.getBoolean(["feature", "alwaysSendChecksum"])
},
"folder": {
"uploads": s.getBaseFolder("uploads"),
@@ -401,6 +402,7 @@ def setSettings():
if "feature" in data.keys():
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 "alwaysSendChecksum" in data["feature"].keys(): s.setBoolean(["feature", "alwaysSendChecksum"], data["feature"]["alwaysSendChecksum"])
if "folder" in data.keys():
if "uploads" in data["folder"].keys(): s.setBaseFolder("uploads", data["folder"]["uploads"])
diff --git a/octoprint/settings.py b/octoprint/settings.py
index 0c7dfad..93a94d1 100644
--- a/octoprint/settings.py
+++ b/octoprint/settings.py
@@ -39,7 +39,8 @@ default_settings = {
},
"feature": {
"gCodeVisualizer": True,
- "waitForStartOnConnect": False
+ "waitForStartOnConnect": False,
+ "alwaysSendChecksum": False
},
"folder": {
"uploads": None,
diff --git a/octoprint/static/js/ui.js b/octoprint/static/js/ui.js
index 48df520..7b0942d 100644
--- a/octoprint/static/js/ui.js
+++ b/octoprint/static/js/ui.js
@@ -959,6 +959,7 @@ function SettingsViewModel() {
self.feature_gcodeViewer = ko.observable(undefined);
self.feature_waitForStart = ko.observable(undefined);
+ self.feature_alwaysSendChecksum = ko.observable(undefined);
self.folder_uploads = ko.observable(undefined);
self.folder_timelapse = ko.observable(undefined);
@@ -1003,6 +1004,7 @@ function SettingsViewModel() {
self.feature_gcodeViewer(response.feature.gcodeViewer);
self.feature_waitForStart(response.feature.waitForStart);
+ self.feature_alwaysSendChecksum(response.feature.alwaysSendChecksum);
self.folder_uploads(response.folder.uploads);
self.folder_timelapse(response.folder.timelapse);
@@ -1035,7 +1037,8 @@ function SettingsViewModel() {
},
"feature": {
"gcodeViewer": self.feature_gcodeViewer(),
- "waitForStart": self.feature_waitForStart()
+ "waitForStart": self.feature_waitForStart(),
+ "alwaysSendChecksum": self.feature_alwaysSendChecksum()
},
"folder": {
"uploads": self.folder_uploads(),
diff --git a/octoprint/templates/settings.html b/octoprint/templates/settings.html
index 9e93f1e..80a4840 100644
--- a/octoprint/templates/settings.html
+++ b/octoprint/templates/settings.html
@@ -106,6 +106,13 @@
+
+
+
+
+
diff --git a/octoprint/util/comm.py b/octoprint/util/comm.py
index 00d63fe..807b86a 100644
--- a/octoprint/util/comm.py
+++ b/octoprint/util/comm.py
@@ -174,7 +174,10 @@ class MachineCom(object):
self._heatupWaitStartTime = 0
self._heatupWaitTimeLost = 0.0
self._printStartTime100 = None
-
+
+ self._alwaysSendChecksum = settings().getBoolean(["feature", "alwaysSendChecksum"])
+ self._currentLine = 0
+
self.thread = threading.Thread(target=self._monitor)
self.thread.daemon = True
self.thread.start()
@@ -344,7 +347,7 @@ class MachineCom(object):
t = time.time()
self._heatupWaitTimeLost = t - self._heatupWaitStartTime
self._heatupWaitStartTime = t
- 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)
if self._state == self.STATE_DETECT_BAUDRATE:
@@ -385,28 +388,28 @@ class MachineCom(object):
else:
self._testingBaudrate = False
elif self._state == self.STATE_CONNECTING:
- if line == '' and startSeen:
+ if (line == "" or "wait" in line) and startSeen:
self._sendCommand("M105")
- elif 'start' in line:
+ elif "start" in line:
startSeen = True
- elif 'ok' in line and startSeen:
+ elif "ok" in line and startSeen:
self._changeState(self.STATE_OPERATIONAL)
elif time.time() > timeout:
self.close()
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.
- if line == '':
+ if line == "" or "wait" in line:
self._sendCommand("M105")
tempRequestTimeout = time.time() + 5
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")
- line = 'ok'
+ line = "ok"
#Even when printing request the temperture every 5 seconds.
if time.time() > tempRequestTimeout:
self._commandQueue.put("M105")
tempRequestTimeout = time.time() + 5
- if 'ok' in line:
+ if "ok" in line:
timeout = time.time() + 5
if not self._commandQueue.empty():
self._sendCommand(self._commandQueue.get())
@@ -460,7 +463,7 @@ class MachineCom(object):
def __del__(self):
self.close()
- def _sendCommand(self, cmd):
+ def _sendCommand(self, cmd, sendChecksum=False):
cmd = cmd.upper()
if self._serial is None:
return
@@ -476,13 +479,23 @@ class MachineCom(object):
self._bedTargetTemp = float(re.search('S([0-9]+)', cmd).group(1))
except:
pass
- self._log('Send: %s' % (cmd))
+
+ commandToSend = cmd
+ self._currentLine += 1
+ if sendChecksum or self._alwaysSendChecksum:
+ lineNumber = self._gcodePos
+ if self._alwaysSendChecksum:
+ lineNumber = self._currentLine
+ checksum = reduce(lambda x,y:x^y, map(ord, "N%d%s" % (lineNumber, cmd)))
+ commandToSend = "N%d%s*%d" % (lineNumber, cmd, checksum)
+
+ self._log('Send: %s' % (commandToSend))
try:
- self._serial.write(cmd + '\n')
+ self._serial.write(commandToSend + '\n')
except serial.SerialTimeoutException:
self._log("Serial timeout while writing to serial port, trying again.")
try:
- self._serial.write(cmd + '\n')
+ self._serial.write(commandToSend + '\n')
except:
self._log("Unexpected error while writing serial port: %s" % (getExceptionString()))
self._errorValue = getExceptionString()
@@ -491,7 +504,16 @@ class MachineCom(object):
self._log("Unexpected error while writing serial port: %s" % (getExceptionString()))
self._errorValue = getExceptionString()
self.close(True)
-
+ finally:
+ if "M110" in cmd:
+ if " N" in cmd:
+ try:
+ self._currentLine = int(re.search("N([0-9]+)", cmd).group(1))
+ except:
+ pass
+ else:
+ self._currentLine = 0
+
def _sendNext(self):
if self._gcodePos >= len(self._gcodeList):
self._changeState(self.STATE_OPERATIONAL)
@@ -515,8 +537,7 @@ class MachineCom(object):
self._callback.mcZChange(z)
except:
self._log("Unexpected error: %s" % (getExceptionString()))
- checksum = reduce(lambda x,y:x^y, map(ord, "N%d%s" % (self._gcodePos, line)))
- self._sendCommand("N%d%s*%d" % (self._gcodePos, line, checksum))
+ self._sendCommand(line, True)
self._gcodePos += 1
self._callback.mcProgress(self._gcodePos)