From b282a18f6bb09bfba86ada1a4e002cac58455ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 9 Jan 2014 20:06:07 +0100 Subject: [PATCH 1/4] Also recognize --iknowwhatimdoing when running as daemon Fixes #337 --- run | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/run b/run index ca1ec2f1..35693ee8 100755 --- a/run +++ b/run @@ -4,7 +4,7 @@ from octoprint.daemon import Daemon from octoprint.server import Server class Main(Daemon): - def __init__(self, pidfile, configfile, basedir, host, port, debug): + def __init__(self, pidfile, configfile, basedir, host, port, debug, allowRoot): Daemon.__init__(self, pidfile) self._configfile = configfile @@ -12,9 +12,10 @@ class Main(Daemon): self._host = host self._port = port self._debug = debug + self._allowRoot = allowRoot def run(self): - octoprint = Server(self._configfile, self._basedir, self._host, self._port, self._debug) + octoprint = Server(self._configfile, self._basedir, self._host, self._port, self._debug, self._allowRoot) octoprint.run() def main(): @@ -50,7 +51,7 @@ def main(): print >> sys.stderr, "Sorry, daemon mode is only supported under Linux right now" sys.exit(2) - daemon = Main(args.pidfile, args.config, args.basedir, args.host, args.port, args.debug) + daemon = Main(args.pidfile, args.config, args.basedir, args.host, args.port, args.debug, args.allowRoot) if "start" == args.daemon: daemon.start() elif "stop" == args.daemon: From 0747336c0f8fd29989bdfaf892696b8fb1336800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 24 Feb 2014 10:00:11 +0100 Subject: [PATCH 2/4] Bugfix: Do not run gcode analyzer when a print is ongoing Evaluate active flag on gcode analyzer AFTER fetching an item from the work queue, otherwise it will always start working once it finds something if the active flag was true once but then switched to false while the queue was still empty. Thanks to @Salandora for spotting this. Fixes #357 (manually cherry-picked from 592f3dc) --- octoprint/gcodefiles.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/octoprint/gcodefiles.py b/octoprint/gcodefiles.py index 3b371213..474ac58f 100644 --- a/octoprint/gcodefiles.py +++ b/octoprint/gcodefiles.py @@ -358,8 +358,6 @@ class MetadataAnalyzer: def _work(self): aborted = None while True: - self._active.wait() - if aborted is not None: filename = aborted aborted = None @@ -368,6 +366,8 @@ class MetadataAnalyzer: (priority, filename) = self._queue.get() self._logger.debug("Processing file %s from queue (priority %d)" % (filename, priority)) + self._active.wait() + try: self._analyzeGcode(filename) self._queue.task_done() From 89cae22b9130865a75d1e8eee15c7924b1a89402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 3 Mar 2014 09:10:10 +0100 Subject: [PATCH 3/4] Extracted all used regexes in the comm layer and precompiled them Possible improvement of #390 --- octoprint/util/comm.py | 50 +++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/octoprint/util/comm.py b/octoprint/util/comm.py index 5be9c2a5..0a2b2737 100644 --- a/octoprint/util/comm.py +++ b/octoprint/util/comm.py @@ -149,6 +149,18 @@ class MachineCom(object): # print job self._currentFile = None + # regexes + floatPattern = "[-+]?[0-9]*\.?[0-9]+" + intPattern = "[0-9]+" + self._regex_command = re.compile("^\s*([GM]\d+)") + self._regex_float = re.compile(floatPattern) + self._regex_paramZFloat = re.compile("Z(%s)" % floatPattern) + self._regex_paramSInt = re.compile("S(%s)" % intPattern) + self._regex_paramNInt = re.compile("N(%s)" % intPattern) + self._regex_minMaxError = re.compile("Error:[0-9]\n") + self._regex_sdPrintingByte = re.compile("([0-9]*)/([0-9]*)") + self._regex_sdFileOpened = re.compile("File opened:\s*(.*?)\s+Size:\s*([0-9]*)") + def __del__(self): self.close() @@ -531,7 +543,7 @@ class MachineCom(object): # Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n" # But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!" # So we can have an extra newline in the most common case. Awesome work people. - if re.match('Error:[0-9]\n', line): + if self._regex_minMaxError.match(line): line = line.rstrip() + self._readline() #Skip the communication errors, as those get corrected. if 'checksum mismatch' in line \ @@ -556,9 +568,9 @@ class MachineCom(object): ##~~ Temperature processing if ' T:' in line or line.startswith('T:'): try: - self._temp = float(re.search("-?[0-9\.]*", line.split('T:')[1]).group(0)) + self._temp = float(self._regex_float.search(line.split('T:')[1]).group(0)) if ' B:' in line: - self._bedTemp = float(re.search("-?[0-9\.]*", line.split(' B:')[1]).group(0)) + self._bedTemp = float(self._regex_float.search(line.split(' B:')[1]).group(0)) self._callback.mcTempUpdate(self._temp, self._bedTemp, self._targetTemp, self._bedTargetTemp) except ValueError: @@ -595,12 +607,12 @@ class MachineCom(object): self._callback.mcSdFiles(self._sdFiles) elif 'SD printing byte' in line: # answer to M27, at least on Marlin, Repetier and Sprinter: "SD printing byte %d/%d" - match = re.search("([0-9]*)/([0-9]*)", line) + match = self._regex_sdPrintingByte.search("([0-9]*)/([0-9]*)", line) self._currentFile.setFilepos(int(match.group(1))) self._callback.mcProgress() elif 'File opened' in line: # answer to M23, at least on Marlin, Repetier and Sprinter: "File opened:%s Size:%d" - match = re.search("File opened:\s*(.*?)\s+Size:\s*([0-9]*)", line) + match = self._regex_sdFileOpened.search(line) self._currentFile = PrintingSdFileInformation(match.group(1), int(match.group(2))) elif 'File selected' in line: # final answer to M23, at least on Marlin, Repetier and Sprinter: "File selected" @@ -855,7 +867,7 @@ class MachineCom(object): return if not self.isStreaming(): - gcode = re.search("^\s*([GM]\d+)", cmd) + gcode = self._regex_command.search(cmd) if gcode: gcode = gcode.group(1) @@ -905,13 +917,15 @@ class MachineCom(object): def _gcode_G0(self, cmd): if 'Z' in cmd: - try: - z = float(re.search('Z([0-9\.]*)', cmd).group(1)) - if self._currentZ != z: - self._currentZ = z - self._callback.mcZChange(z) - except ValueError: - pass + match = self._regex_paramZFloat.search(cmd) + if match: + try: + z = float(match.group(1)) + if self._currentZ != z: + self._currentZ = z + self._callback.mcZChange(z) + except ValueError: + pass return cmd _gcode_G1 = _gcode_G0 @@ -921,7 +935,7 @@ class MachineCom(object): _gcode_M1 = _gcode_M0 def _gcode_M104(self, cmd): - match = re.search('S([0-9]+)', cmd) + match = self._regex_paramSInt.search(cmd) if match: try: self._targetTemp = float(match.group(1)) @@ -930,7 +944,7 @@ class MachineCom(object): return cmd def _gcode_M140(self, cmd): - match = re.search('S([0-9]+)', cmd) + match = self._regex_paramSInt.search(cmd) if match: try: self._bedTargetTemp = float(match.group(1)) @@ -948,7 +962,7 @@ class MachineCom(object): def _gcode_M110(self, cmd): newLineNumber = None - match = re.search("N([0-9]+)", cmd) + match = self._regex_paramNInt.search(cmd) if match: try: newLineNumber = int(match.group(1)) @@ -1083,7 +1097,7 @@ class PrintingGcodeFileInformation(PrintingFileInformation): self._firstLine = None self._offsetCallback = offsetCallback - self._tempCommandPattern = re.compile("^\s*M(104|109|140|190)\s+S([0-9\.]+)") + self._regex_tempCommand = re.compile("^\s*M(104|109|140|190)\s+S([0-9\.]+)") if not os.path.exists(self._filename) or not os.path.isfile(self._filename): raise IOError("File %s does not exist" % self._filename) @@ -1140,7 +1154,7 @@ class PrintingGcodeFileInformation(PrintingFileInformation): if self._offsetCallback is not None: (tempOffset, bedTempOffset) = self._offsetCallback() if tempOffset != 0 or bedTempOffset != 0: - tempMatch = self._tempCommandPattern.match(line) + tempMatch = self._regex_tempCommand.match(line) if tempMatch is not None: if tempMatch.group(1) == "104" or tempMatch.group(1) == "109": offset = tempOffset From f09d44d8a095a86fda84a168f77bab283d1397be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 3 Mar 2014 16:58:15 +0100 Subject: [PATCH 4/4] Hopefully fixed a race condition that could occur when pressing "Print" (file not opened yet, but comm layer tries to fetch next command) Possible fix for #400 --- octoprint/util/comm.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/octoprint/util/comm.py b/octoprint/util/comm.py index 0a2b2737..c0b31f96 100644 --- a/octoprint/util/comm.py +++ b/octoprint/util/comm.py @@ -341,14 +341,14 @@ class MachineCom(object): if self._currentFile is None: raise ValueError("No file selected for printing") - wasPaused = self.isPaused() - self._printSection = "CUSTOM" - self._changeState(self.STATE_PRINTING) - eventManager().fire("PrintStarted", self._currentFile.getFilename()) try: self._currentFile.start() + + self._changeState(self.STATE_PRINTING) + eventManager().fire("PrintStarted", self._currentFile.getFilename()) + if self.isSdFileSelected(): if wasPaused: self.sendCommand("M26 S0") @@ -620,7 +620,6 @@ class MachineCom(object): eventManager().fire("FileSelected", self._currentFile.getFilename()) elif 'Writing to file' in line: # anwer to M28, at least on Marlin, Repetier and Sprinter: "Writing to file: %s" - self._printSection = "CUSTOM" self._changeState(self.STATE_PRINTING) line = "ok" elif 'Done printing file' in line: