From 43cd85b8e4889afa08da3cc55f4b5e3402130a30 Mon Sep 17 00:00:00 2001 From: Ross Hendrickson Date: Sat, 3 Aug 2013 04:07:38 +0000 Subject: [PATCH] Slicing STL and sending to gcode to SD card in place --- octoprint/cura/__init__.py | 6 ++++- octoprint/filemanager/destinations.py | 4 +++ octoprint/gcodefiles.py | 39 ++++++++++++--------------- octoprint/printer.py | 21 +++++++++------ octoprint/server.py | 11 +++++++- octoprint/util/comm.py | 4 +++ 6 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 octoprint/filemanager/destinations.py diff --git a/octoprint/cura/__init__.py b/octoprint/cura/__init__.py index 54c7685d..6872bc21 100644 --- a/octoprint/cura/__init__.py +++ b/octoprint/cura/__init__.py @@ -4,6 +4,7 @@ __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agp import logging from octoprint.settings import settings +from octoprint.gcodefiles import GcodeManager class CuraFactory(object): @@ -47,7 +48,10 @@ class CuraEngine(object): logging.info("Subprocess args: %s" % str(call_args)) process = subprocess.call(call_args) call_back(*call_back_args) - logging.info("Slicing call back complete") + # TODO: Figure out a better way to have the file manager refresh + manager = GcodeManager() + manager.processGcode(call_args[4]) + logging.info("Slicing call back complete:%s" % str(call_back)) args = [self.cura_path, '-s', config, '-o', gcode, file_path] logging.info('CuraEngine args:%s' % str(args)) diff --git a/octoprint/filemanager/destinations.py b/octoprint/filemanager/destinations.py new file mode 100644 index 00000000..b4af5183 --- /dev/null +++ b/octoprint/filemanager/destinations.py @@ -0,0 +1,4 @@ +class FileDestinations(object): + + SDCARD = "sdcard" + LOCAL = "local" diff --git a/octoprint/gcodefiles.py b/octoprint/gcodefiles.py index 158039fc..72a94738 100644 --- a/octoprint/gcodefiles.py +++ b/octoprint/gcodefiles.py @@ -117,14 +117,19 @@ class GcodeManager: #~~ file handling - def addFile(self, file): + def addFile(self, file, destination): from octoprint.util import isSTLFileName from octoprint.util import isGcodeFileName + from octoprint.filemanager.destinations import FileDestinations - if not file: + if not file or not destination: return None + local = True if destination == FileDestinations.LOCAL else False + absolutePath = self.getAbsolutePath(file.filename, mustExist=False) + + logging.info("Adding file:%s" % absolutePath) if absolutePath is None: return None @@ -133,19 +138,22 @@ class GcodeManager: filename = file.filename if isGcodeFileName(filename): + logging.info("File is Gcode File") return self.processGcode(absolutePath) curaEnabled = self._settings.get(["curaEngine", "enabled"]) + logging.info("Cura Enabled %s" % str(curaEnabled)) - if isSTLFileName(filename) and curaEnabled: + if isSTLFileName(filename) and curaEnabled and local: + logging.info("File is STL - Needs to be sliced") gcodePath = util.genGcodeFileName(absolutePath) logging.info("FILENAME: %s" % filename) callBackArgs = [gcodePath] callBack = self.processGcode - return self.processSTL( - filename, absolutePath, callBack, callBackArgs) + self.processSTL(absolutePath, callBack, callBackArgs) + return filename def getFutureFileName(self, file): if not file: @@ -157,21 +165,21 @@ class GcodeManager: return self._getBasicFilename(absolutePath) - - def processSTL(self, filename, absolutePath, callBack, callBackArgs): + def processSTL(self, absolutePath, callBack, callBackArgs): from octoprint.cura import CuraFactory curaEngine = CuraFactory.create_slicer() - gcodePath = util.genGcodeFileName(absolutePath) - config = self._settings.get(["curaEngine", "config"]) curaEngine.process_file( config, gcodePath, absolutePath, callBack, callBackArgs) def processGcode(self, absolutePath): + logging.info("Processing Gcode:%s" % str(absolutePath)) + if absolutePath is None: + return None filename = self._getBasicFilename(absolutePath) @@ -185,19 +193,6 @@ class GcodeManager: return filename - if absolutePath is None: - return None - - basename = self._getBasicFilename(absolutePath) - if basename in self._metadata.keys(): - # delete existing metadata entry, since the file is going to get overwritten - del self._metadata[basename] - self._metadataDirty = True - self._saveMetadata() - file.save(absolutePath) - self._metadataAnalyzer.addFileToQueue(basename) - return basename - def getFutureFilename(self, file): if not file: return None diff --git a/octoprint/printer.py b/octoprint/printer.py index ae080ea3..0770da15 100644 --- a/octoprint/printer.py +++ b/octoprint/printer.py @@ -7,6 +7,7 @@ import datetime import threading import copy import os +import logging #import logging, logging.config @@ -462,31 +463,35 @@ class Printer(): def addSdFile(self, filename, absolutePath): from octoprint.util import isGcodeFileName from octoprint.util import isSTLFileName + from octoprint.gcodefiles import GcodeManager + logging.info("Adding SD Card file:%s" % filename) if not self._comm or self._comm.isBusy(): + logging.error("No connection to printer or printer is busy") return if isGcodeFileName(filename): + logging.info("Sending Gcode to SD card") self.streamSdFile(filename, absolutePath) if isSTLFileName(filename): + logging.info("Slicing stl and then sending to SD card") gcodePath = util.genGcodeFileName(absolutePath) - callBackArgs = [filename, absolutePath] + gcodeFileName = util.genGcodeFileName(filename) + callBackArgs = [gcodeFileName, gcodePath] callBack = self.streamSdFile gcodeManager = GcodeManager() gcodeManager.processSTL( - filename, absolutePath, callBack, callBackArgs) + absolutePath, callBack, callBackArgs) - def streamSdFile(filename, absolutePath): - self._sdStreamer = SdFileStreamer(self._comm, filename, absolutePath, self._onSdFileStreamProgress, self._onSdFileStreamFinish) - self._sdStreamer.start() - logging.info("Stream file to SD started") - - def addSdFile(self, filename, path): + def streamSdFile(self, filename, path): + logging.info("Stream SD file called:%s" % filename) if not self._comm or self._comm.isBusy(): return + logging.info("Starting to stream file") self._comm.startFileTransfer(path, filename[:8].lower() + ".gco") + logging.info("File is streaming to SD Card") def deleteSdFile(self, filename): if not self._comm: diff --git a/octoprint/server.py b/octoprint/server.py index f02c87ce..c1c5140e 100644 --- a/octoprint/server.py +++ b/octoprint/server.py @@ -19,6 +19,8 @@ import octoprint.timelapse import octoprint.gcodefiles as gcodefiles import octoprint.util as util import octoprint.users as users +from octoprint.filemanager.destinations import FileDestinations + import octoprint.events as events @@ -311,12 +313,16 @@ def readGcodeFile(filename): @login_required def uploadGcodeFile(): if "gcode_file" in request.files.keys(): + logging.info("Uploading Gcode File") file = request.files["gcode_file"] sd = "target" in request.values.keys() and request.values["target"] == "sd"; + logging.info("SD:%s" % str(sd)) + currentFilename = None currentSd = None currentJob = printer.getCurrentJob() + logging.info("Current Job:%s" % str(currentJob)) if currentJob is not None and "filename" in currentJob.keys() and "sd" in currentJob.keys(): currentFilename = currentJob["filename"] currentSd = currentJob["sd"] @@ -329,13 +335,16 @@ def uploadGcodeFile(): # trying to overwrite currently selected file, but it is being printed return make_response("Trying to overwrite file that is currently being printed: %s" % currentFilename, 403) - filename = gcodeManager.addFile(file) + destination = FileDestinations.SDCARD if sd else FileDestinations.LOCAL + + filename = gcodeManager.addFile(file, destination) if filename is None: return make_response("Could not upload the file %s" % file.filename, 500) absFilename = gcodeManager.getAbsolutePath(filename) if sd: + logging.info("Add to SD file") printer.addSdFile(filename, absFilename) if currentFilename == filename and currentSd == sd: diff --git a/octoprint/util/comm.py b/octoprint/util/comm.py index 32f66c76..ce7e1f77 100644 --- a/octoprint/util/comm.py +++ b/octoprint/util/comm.py @@ -332,10 +332,13 @@ class MachineCom(object): eventManager().fire("Error", self.getErrorString()) def startFileTransfer(self, filename, remoteFilename): + logging.info("Starting File Transfer:%s" % filename) if not self.isOperational() or self.isBusy(): + logging.info("Printer is not operation or busy") return self._currentFile = StreamingGcodeFileInformation(filename) + logging.info("Starting to send currentfile:%s" % str(self._currentFile)) self._currentFile.start() self.sendCommand("M28 %s" % remoteFilename) @@ -350,6 +353,7 @@ class MachineCom(object): if not self.isOperational(): # printer is not connected, can't use SD return + logging.info("Select SD file: %s" % filename) self.sendCommand("M23 %s" % filename) else: self._currentFile = PrintingGcodeFileInformation(filename)