From d12da2548f4ba08a7fe6f17cfb863c1865e36b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Sun, 25 Aug 2013 15:03:27 +0200 Subject: [PATCH 1/3] New option "swallowOkAfterResend" for Repetier, changed initial linenumber for serial comm to 1 --- octoprint/server.py | 4 +- octoprint/settings.py | 11 ++- .../static/js/app/viewmodels/settings.js | 5 +- octoprint/templates/settings.jinja2 | 7 ++ octoprint/util/comm.py | 15 ++-- octoprint/util/virtual.py | 68 +++++++++++++------ 6 files changed, 84 insertions(+), 26 deletions(-) diff --git a/octoprint/server.py b/octoprint/server.py index 001a0a3a..ffa9a992 100644 --- a/octoprint/server.py +++ b/octoprint/server.py @@ -576,7 +576,8 @@ def getSettings(): "gcodeViewer": s.getBoolean(["feature", "gCodeVisualizer"]), "waitForStart": s.getBoolean(["feature", "waitForStartOnConnect"]), "alwaysSendChecksum": s.getBoolean(["feature", "alwaysSendChecksum"]), - "sdSupport": s.getBoolean(["feature", "sdSupport"]) + "sdSupport": s.getBoolean(["feature", "sdSupport"]), + "swallowOkAfterResend": s.getBoolean(["feature", "swallowOkAfterResend"]) }, "serial": { "port": connectionOptions["portPreference"], @@ -640,6 +641,7 @@ def setSettings(): 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 "sdSupport" in data["feature"].keys(): s.setBoolean(["feature", "sdSupport"], data["feature"]["sdSupport"]) + if "swallowOkAfterResend" in data["feature"].keys(): s.setBoolean(["feature", "swallowOkAfterResend"], data["feature"]["swallowOkAfterResend"]) if "serial" in data.keys(): if "autoconnect" in data["serial"].keys(): s.setBoolean(["serial", "autoconnect"], data["serial"]["autoconnect"]) diff --git a/octoprint/settings.py b/octoprint/settings.py index 2d05f9b1..5b6060b8 100644 --- a/octoprint/settings.py +++ b/octoprint/settings.py @@ -52,7 +52,8 @@ default_settings = { "gCodeVisualizer": True, "waitForStartOnConnect": False, "alwaysSendChecksum": False, - "sdSupport": True + "sdSupport": True, + "swallowOkAfterResend": False }, "folder": { "uploads": None, @@ -104,6 +105,14 @@ default_settings = { "api": { "enabled": False, "key": ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes) + }, + "devel": { + "virtualPrinter": { + "enabled": False, + "okAfterResend": False, + "forceChecksum": False, + "okWithLinenumber": False + } } } diff --git a/octoprint/static/js/app/viewmodels/settings.js b/octoprint/static/js/app/viewmodels/settings.js index 7c01f9d7..8b27bbeb 100644 --- a/octoprint/static/js/app/viewmodels/settings.js +++ b/octoprint/static/js/app/viewmodels/settings.js @@ -30,6 +30,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) { self.feature_waitForStart = ko.observable(undefined); self.feature_alwaysSendChecksum = ko.observable(undefined); self.feature_sdSupport = ko.observable(undefined); + self.feature_swallowOkAfterResend = ko.observable(undefined); self.serial_port = ko.observable(); self.serial_baudrate = ko.observable(); @@ -91,6 +92,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) { self.feature_waitForStart(response.feature.waitForStart); self.feature_alwaysSendChecksum(response.feature.alwaysSendChecksum); self.feature_sdSupport(response.feature.sdSupport); + self.feature_swallowOkAfterResend(response.feature.swallowOkAfterResend); self.serial_port(response.serial.port); self.serial_baudrate(response.serial.baudrate); @@ -141,7 +143,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) { "gcodeViewer": self.feature_gcodeViewer(), "waitForStart": self.feature_waitForStart(), "alwaysSendChecksum": self.feature_alwaysSendChecksum(), - "sdSupport": self.feature_sdSupport() + "sdSupport": self.feature_sdSupport(), + "swallowOkAfterResend": self.feature_swallowOkAfterResend() }, "serial": { "port": self.serial_port(), diff --git a/octoprint/templates/settings.jinja2 b/octoprint/templates/settings.jinja2 index 0bed27c9..a116d43b 100644 --- a/octoprint/templates/settings.jinja2 +++ b/octoprint/templates/settings.jinja2 @@ -195,6 +195,13 @@ +
+
+ +
+
diff --git a/octoprint/util/comm.py b/octoprint/util/comm.py index 40c420b7..f31fb023 100644 --- a/octoprint/util/comm.py +++ b/octoprint/util/comm.py @@ -49,7 +49,7 @@ def serialList(): if prev in baselist: baselist.remove(prev) baselist.insert(0, prev) - if isDevVersion(): + if settings().getBoolean(["devel", "virtualPrinter", "enabled"]): baselist.append("VIRTUAL") return baselist @@ -121,7 +121,7 @@ class MachineCom(object): self._heatupWaitTimeLost = 0.0 self._alwaysSendChecksum = settings().getBoolean(["feature", "alwaysSendChecksum"]) - self._currentLine = 0 + self._currentLine = 1 self._resendDelta = None self._lastLines = deque([], 50) @@ -498,6 +498,7 @@ class MachineCom(object): sdStatusRequestTimeout = timeout startSeen = not settings().getBoolean(["feature", "waitForStartOnConnect"]) heatingUp = False + swallowOk = False while True: try: line = self._readline() @@ -703,6 +704,8 @@ class MachineCom(object): tempRequestTimeout = getNewTimeout("communication") # resend -> start resend procedure from requested line elif line.lower().startswith("resend") or line.lower().startswith("rs"): + if settings().get(["feature", "swallowOkAfterResend"]): + swallowOk = True self._handleResendRequest(line) ### Printing @@ -728,7 +731,9 @@ class MachineCom(object): self._commandQueue.put("M105") tempRequestTimeout = getNewTimeout("communication") - if 'ok' in line: + if "ok" in line and swallowOk: + swallowOk = False + elif "ok" in line: timeout = getNewTimeout("communication") if self._resendDelta is not None: self._resendNextCommand() @@ -737,6 +742,8 @@ class MachineCom(object): else: self._sendNext() elif line.lower().startswith("resend") or line.lower().startswith("rs"): + if settings().get(["feature", "swallowOkAfterResend"]): + swallowOk = True self._handleResendRequest(line) except: self._logger.exception("Something crashed inside the serial connection loop, please report this in OctoPrint's bug tracker:") @@ -798,7 +805,7 @@ class MachineCom(object): if lineToResend is not None: self._resendDelta = self._currentLine - lineToResend - if self._resendDelta > len(self._lastLines) or len(self._lastLines) == 0: + if self._resendDelta > len(self._lastLines) or len(self._lastLines) == 0 or self._resendDelta <= 0: self._errorValue = "Printer requested line %d but no sufficient history is available, can't resend" % lineToResend self._logger.warn(self._errorValue) if self.isPrinting(): diff --git a/octoprint/util/virtual.py b/octoprint/util/virtual.py index cf699f6c..6a445593 100644 --- a/octoprint/util/virtual.py +++ b/octoprint/util/virtual.py @@ -32,6 +32,7 @@ class VirtualPrinter(): self._newSdFilePos = None self.currentLine = 0 + self.lastN = 0 waitThread = threading.Thread(target=self._sendWaitAfterTimeout) waitThread.start() @@ -40,18 +41,49 @@ class VirtualPrinter(): if self.readList is None: return - # strip checksum data = data.strip() + + # strip checksum if "*" in data: data = data[:data.rfind("*")] self.currentLine += 1 + elif settings().getBoolean(["devel", "virtualPrinter", "forceChecksum"]): + self.readList.append("Error: Missing checksum") + return + + # track N = N + 1 + if data.startswith("N") and "M110" in data: + linenumber = int(re.search("N([0-9]+)", data).group(1)) + self.lastN = linenumber + self.currentLine = linenumber + return + elif data.startswith("N"): + linenumber = int(re.search("N([0-9]+)", data).group(1)) + expected = self.lastN + 1 + if linenumber != expected: + self.readList.append("Error: expected line %d got %d" % (expected, linenumber)) + self.readList.append("Resend:%d" % expected) + if settings().getBoolean(["devel", "virtualPrinter", "okAfterResend"]): + self.readList.append("ok") + return + elif self.currentLine == 100: + # simulate a resend at line 100 of the last 5 lines + self.lastN = 94 + self.readList.append("Error: Line Number is not Last Line Number\n") + self.readList.append("rs %d\n" % (self.currentLine - 5)) + if settings().getBoolean(["devel", "virtualPrinter", "okAfterResend"]): + self.readList.append("ok") + return + else: + self.lastN = linenumber + data += "\n" # shortcut for writing to SD if self._writingToSd and not self._selectedSdFile is None and not "M29" in data: with open(self._selectedSdFile, "a") as f: f.write(data) - self.readList.append("ok") + self._sendOk() return #print "Send: %s" % (data.rstrip()) @@ -105,11 +137,6 @@ class VirtualPrinter(): if self._sdCardReady: filename = data.split(None, 1)[1].strip() self._deleteSdFile(filename) - elif "M110" in data: - # reset current line - self.currentLine = int(re.search('^N([0-9]+)', data).group(1)) - self.readList.append("reset line to %r\n" % self.currentLine) - self.readList.append("ok\n") elif "M114" in data: # send dummy position report self.readList.append("ok C: X:10.00 Y:3.20 Z:5.20 E:1.24") @@ -119,19 +146,15 @@ class VirtualPrinter(): elif "M999" in data: # mirror Marlin behaviour self.readList.append("Resend: 1") - 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: - self.readList.append("ok\n") + self._sendOk() def _listSd(self): self.readList.append("Begin file list") for osFile in os.listdir(self._virtualSd): self.readList.append(osFile.upper()) self.readList.append("End file list") - self.readList.append("ok") + self._sendOk() def _selectSdFile(self, filename): file = os.path.join(self._virtualSd, filename).lower() @@ -149,11 +172,11 @@ class VirtualPrinter(): self._sdPrinter = threading.Thread(target=self._sdPrintingWorker) self._sdPrinter.start() self._sdPrintingSemaphore.set() - self.readList.append("ok") + self._sendOk() def _pauseSdPrint(self): self._sdPrintingSemaphore.clear() - self.readList.append("ok") + self._sendOk() def _setSdPos(self, pos): self._newSdFilePos = pos @@ -175,12 +198,12 @@ class VirtualPrinter(): self._writingToSd = True self._selectedSdFile = file self.readList.append("Writing to file: %s" % filename) - self.readList.append("ok") + self._sendOk() def _finishSdFile(self): self._writingToSd = False self._selectedSdFile = None - self.readList.append("ok") + self._sendOk() def _sdPrintingWorker(self): self._selectedSdFilePos = 0 @@ -220,7 +243,7 @@ class VirtualPrinter(): file = os.path.join(self._virtualSd, filename) if os.path.exists(file) and os.path.isfile(file): os.remove(file) - self.readList.append("ok") + self._sendOk() def readline(self): if self.readList is None: @@ -249,7 +272,14 @@ class VirtualPrinter(): def close(self): self.readList = None + def _sendOk(self): + if settings().getBoolean(["devel", "virtualPrinter", "okWithLinenumber"]): + self.readList.append("ok %d" % self.lastN) + else: + self.readList.append("ok") + def _sendWaitAfterTimeout(self, timeout=5): time.sleep(timeout) - self.readList.append("wait") + if self.readList is not None: + self.readList.append("wait") From edcc11376e79cc1d2f58f7ff462e03b2d73c308c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Tue, 27 Aug 2013 22:15:11 +0200 Subject: [PATCH 2/3] Fixed merge error --- octoprint/settings.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/octoprint/settings.py b/octoprint/settings.py index f1a73709..59ae4611 100644 --- a/octoprint/settings.py +++ b/octoprint/settings.py @@ -109,8 +109,7 @@ default_settings = { "terminalFilters": [ { "name": "Suppress M105 requests/responses", "regex": "(Send: M105)|(Recv: ok T:)" }, { "name": "Suppress M27 requests/responses", "regex": "(Send: M27)|(Recv: SD printing byte)" } - ] - }, + ], "devel": { "virtualPrinter": { "enabled": False, From f6173e7dc84f6643420e6a13fd21903537ebb941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 29 Aug 2013 20:25:32 +0200 Subject: [PATCH 3/3] Allow switching off the heaters via the profiles again Closes #240 --- octoprint/static/js/app/viewmodels/temperature.js | 8 ++++++++ octoprint/templates/index.jinja2 | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/octoprint/static/js/app/viewmodels/temperature.js b/octoprint/static/js/app/viewmodels/temperature.js index 7924cd4c..1d7b9953 100644 --- a/octoprint/static/js/app/viewmodels/temperature.js +++ b/octoprint/static/js/app/viewmodels/temperature.js @@ -154,6 +154,10 @@ function TemperatureViewModel(loginStateViewModel, settingsViewModel) { self._updateTemperature(self.newTemp(), "temp", function(){self.targetTemp(self.newTemp()); self.newTemp("");}); }; + self.setTempToZero = function() { + self._updateTemperature(0, "temp", function(){self.targetTemp(0); self.newTemp("");}); + } + self.setBedTempFromProfile = function(profile) { self._updateTemperature(profile.bed, "bedTemp"); } @@ -162,6 +166,10 @@ function TemperatureViewModel(loginStateViewModel, settingsViewModel) { self._updateTemperature(self.newBedTemp(), "bedTemp", function() {self.bedTargetTemp(self.newBedTemp()); self.newBedTemp("");}); }; + self.setBedTempToZero = function() { + self._updateTemperature(0, "bedTemp", function() {self.bedTargetTemp(0); self.newBedTemp("");}); + } + self._updateTemperature = function(temp, type, callback) { var data = {}; data[type] = temp; diff --git a/octoprint/templates/index.jinja2 b/octoprint/templates/index.jinja2 index f56a614f..1fc1ea1b 100644 --- a/octoprint/templates/index.jinja2 +++ b/octoprint/templates/index.jinja2 @@ -275,7 +275,7 @@
  • - Off + Off
  • @@ -307,7 +307,7 @@
  • - Off + Off