diff --git a/src/octoprint/plugins/svgtogcode/__init__.py b/src/octoprint/plugins/svgtogcode/__init__.py index 8712125c..61ed595d 100644 --- a/src/octoprint/plugins/svgtogcode/__init__.py +++ b/src/octoprint/plugins/svgtogcode/__init__.py @@ -253,14 +253,6 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin, ##~~ TemplatePlugin API - def get_template_vars(self): - return dict() - - def get_template_folder(self): - #import os - #return os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates") - return os.path.join(self._basefolder, "templates") - def get_template_configs(self): return [ dict(type = 'settings', name = "Svg Conversion", template='svgtogcode_settings.jinja2', custom_bindings = False), diff --git a/src/octoprint/printer/__init__.py b/src/octoprint/printer/__init__.py index 49aae2dd..d1f7b832 100644 --- a/src/octoprint/printer/__init__.py +++ b/src/octoprint/printer/__init__.py @@ -303,408 +303,6 @@ class PrinterInterface(object): raise NotImplementedError() def jog(self, axis, amount): -#<<<<<<< HEAD -# printer_profile = self._printerProfileManager.get_current_or_default() -# movement_speed = printer_profile["axes"][axis]["speed"] -# self.commands(["G91", "G1 %s%.4f F%d" % (axis.upper(), amount, movement_speed), "G90", "?"]) -# -# def position(self, x, y): -# printer_profile = self._printerProfileManager.get_current_or_default() -# movement_speed = min(printer_profile["axes"]["x"]["speed"], printer_profile["axes"]["y"]["speed"]) -# self.commands(["G90", "G0 X%.3f Y%.3f F%d" % (x, y, movement_speed), "?"]) -# -# def home(self, axes): -# if(settings().getBoolean(["feature", "grbl"])): -# self.commands(["$H", "G92X0Y0Z0", "G90", "G21"]) -# else: -# self.commands(["G91", "G28 %s" % " ".join(map(lambda x: "%s0" % x.upper(), axes)), "G90"]) -# -# def extrude(self, amount): -# printer_profile = self._printerProfileManager.get_current_or_default() -# extrusion_speed = printer_profile["axes"]["e"]["speed"] -# self.commands(["G91", "G1 E%s F%d" % (amount, extrusion_speed), "G90"]) -# -# def changeTool(self, tool): -# try: -# toolNum = int(tool[len("tool"):]) -# self.command("T%d" % toolNum) -# except ValueError: -# pass -# -# def setTemperature(self, type, value): -# if type.startswith("tool"): -# printer_profile = self._printerProfileManager.get_current_or_default() -# extruder_count = printer_profile["extruder"]["count"] -# if extruder_count > 1: -# try: -# toolNum = int(type[len("tool"):]) -# self.command("M104 T%d S%f" % (toolNum, value)) -# except ValueError: -# pass -# else: -# self.command("M104 S%f" % value) -# elif type == "bed": -# self.command("M140 S%f" % value) -# -# def setTemperatureOffset(self, offsets={}): -# if self._comm is None: -# return -# -# tool, bed = self._comm.getOffsets() -# -# validatedOffsets = {} -# -# for key in offsets: -# value = offsets[key] -# if key == "bed": -# bed = value -# validatedOffsets[key] = value -# elif key.startswith("tool"): -# try: -# toolNum = int(key[len("tool"):]) -# tool[toolNum] = value -# validatedOffsets[key] = value -# except ValueError: -# pass -# -# self._comm.setTemperatureOffset(tool, bed) -# self._stateMonitor.setTempOffsets(validatedOffsets) -# -# def selectFile(self, filename, sd, printAfterSelect=False): -# if self._comm is None or (self._comm.isBusy() or self._comm.isStreaming()): -# self._logger.info("Cannot load file: printer not connected or currently busy") -# return -# -# self._printAfterSelect = printAfterSelect -# self._comm.selectFile(filename, sd) -# self._setProgressData(0, None, None, None) -# self._setCurrentZ(None) -# -# def unselectFile(self): -# if self._comm is not None and (self._comm.isBusy() or self._comm.isStreaming()): -# return -# -# self._comm.unselectFile() -# self._setProgressData(0, None, None, None) -# self._setCurrentZ(None) -# -# def startPrint(self): -# """ -# Starts the currently loaded print job. -# Only starts if the printer is connected and operational, not currently printing and a printjob is loaded -# """ -# if self._comm is None or not self._comm.isOperational() or self._comm.isPrinting(): -# return -# if self._selectedFile is None: -# return -# -# self._timeEstimationData = TimeEstimationHelper() -# self._lastProgressReport = None -# self._setCurrentZ(None) -# self._comm.startPrint() -# self._addPositionData(None, None) -# -# def _addPositionData(self, MPos, WPos): -# -# if MPos is None or WPos is None: -# MPosString = WPosString = "-" -# else: -# MPosString = "X: %.4f Y: %.4f Z: %.4f" % ( MPos[0], MPos[1], MPos[2] ) -# WPosString = "X: %.4f Y: %.4f Z: %.4f" % ( WPos[0], WPos[1], WPos[2] ) -# -# -# self._stateMonitor.setWorkPosition(WPosString) -# self._stateMonitor.setMachinePosition(MPosString) -# -# def togglePausePrint(self): -# """ -# Pause the current printjob. -# """ -# if self._comm is None: -# return -# -# self._comm.setPause(not self._comm.isPaused()) -# -# def cancelPrint(self, disableMotorsAndHeater=True): -# """ -# Cancel the current printjob. -# """ -# if self._comm is None: -# return -# -# self._comm.cancelPrint() -# -# if disableMotorsAndHeater: -# printer_profile = self._printerProfileManager.get_current_or_default() -# extruder_count = printer_profile["extruder"]["count"] -# -# # disable motors, switch off hotends, bed and fan -# #commands = ["M84"] -# #commands.extend(map(lambda x: "M104 T%d S0" % x, range(extruder_count))) -# #commands.extend(["M140 S0", "M106 S0"]) -# commands = ["M05", "G0X0Y0", "M09"] -# self.commands(commands) -# -# # reset progress, height, print time -# self._setCurrentZ(None) -# self._setProgressData(None, None, None, None) -# -# # mark print as failure -# if self._selectedFile is not None: -# self._fileManager.log_print(FileDestinations.SDCARD if self._selectedFile["sd"] else FileDestinations.LOCAL, self._selectedFile["filename"], time.time(), self._comm.getPrintTime(), False, self._printerProfileManager.get_current_or_default()["id"]) -# payload = { -# "file": self._selectedFile["filename"], -# "origin": FileDestinations.LOCAL -# } -# if self._selectedFile["sd"]: -# payload["origin"] = FileDestinations.SDCARD -# eventManager().fire(Events.PRINT_FAILED, payload) -# -# #~~ state monitoring -# -# def _setCurrentZ(self, currentZ): -# self._currentZ = currentZ -# self._stateMonitor.setCurrentZ(self._currentZ) -# -# def _setState(self, state): -# self._state = state -# self._stateMonitor.setState({"text": self.getStateString(), "flags": self._getStateFlags()}) -# -# def _addLog(self, log): -# self._log.append(log) -# self._stateMonitor.addLog(log) -# -# def _addMessage(self, message): -# self._messages.append(message) -# self._stateMonitor.addMessage(message) -# -# def _estimateTotalPrintTime(self, progress, printTime): -# if not progress or not printTime or not self._timeEstimationData: -# #self._estimationLogger.info("{progress};{printTime};;;;".format(**locals())) -# return None -# -# else: -# newEstimate = printTime / progress -# self._timeEstimationData.update(newEstimate) -# -# result = None -# if self._timeEstimationData.is_stable(): -# result = self._timeEstimationData.average_total_rolling -# -# #averageTotal = self._timeEstimationData.average_total -# #averageTotalRolling = self._timeEstimationData.average_total_rolling -# #averageDistance = self._timeEstimationData.average_distance -# -# #self._estimationLogger.info("{progress};{printTime};{newEstimate};{averageTotal};{averageTotalRolling};{averageDistance}".format(**locals())) -# -# return result -# -# def _setProgressData(self, progress, filepos, printTime, cleanedPrintTime): -# estimatedTotalPrintTime = self._estimateTotalPrintTime(progress, cleanedPrintTime) -# statisticalTotalPrintTime = None -# totalPrintTime = estimatedTotalPrintTime -# -# if self._selectedFile and "estimatedPrintTime" in self._selectedFile and self._selectedFile["estimatedPrintTime"]: -# statisticalTotalPrintTime = self._selectedFile["estimatedPrintTime"] -# if progress and cleanedPrintTime: -# if estimatedTotalPrintTime is None: -# totalPrintTime = statisticalTotalPrintTime -# else: -# if progress < 0.5: -# sub_progress = progress * 2 -# else: -# sub_progress = 1.0 -# totalPrintTime = (1 - sub_progress) * statisticalTotalPrintTime + sub_progress * estimatedTotalPrintTime -# -# #self._printTimeLogger.info("{progress};{cleanedPrintTime};{estimatedTotalPrintTime};{statisticalTotalPrintTime};{totalPrintTime}".format(**locals())) -# -# self._progress = progress -# self._printTime = printTime -# self._printTimeLeft = totalPrintTime - cleanedPrintTime if (totalPrintTime is not None and cleanedPrintTime is not None) else None -# -# self._stateMonitor.setProgress({ -# "completion": self._progress * 100 if self._progress is not None else None, -# "filepos": filepos, -# "printTime": int(self._printTime) if self._printTime is not None else None, -# "printTimeLeft": int(self._printTimeLeft) if self._printTimeLeft is not None else None -# }) -# -# if progress: -# progress_int = int(progress * 100) -# if self._lastProgressReport != progress_int: -# self._lastProgressReport = progress_int -# self._reportPrintProgressToPlugins(progress_int) -# -# -# def _addTemperatureData(self, temp, bedTemp): -# currentTimeUtc = int(time.time()) -# -# data = { -# "time": currentTimeUtc -# } -# for tool in temp.keys(): -# data["tool%d" % tool] = { -# "actual": temp[tool][0], -# "target": temp[tool][1] -# } -# if bedTemp is not None and isinstance(bedTemp, tuple): -# data["bed"] = { -# "actual": bedTemp[0], -# "target": bedTemp[1] -# } -# -# self._temps.append(data) -# -# self._temp = temp -# self._bedTemp = bedTemp -# -# self._stateMonitor.addTemperature(data) -# -# def _setJobData(self, filename, filesize, sd): -# if filename is not None: -# self._selectedFile = { -# "filename": filename, -# "filesize": filesize, -# "sd": sd, -# "estimatedPrintTime": None -# } -# else: -# self._selectedFile = None -# self._stateMonitor.setJobData({ -# "file": { -# "name": None, -# "origin": None, -# "size": None, -# "date": None -# }, -# "estimatedPrintTime": None, -# "averagePrintTime": None, -# "lastPrintTime": None, -# "filament": None, -# }) -# return -# -# estimatedPrintTime = None -# lastPrintTime = None -# averagePrintTime = None -# date = None -# filament = None -# if filename: -# # Use a string for mtime because it could be float and the -# # javascript needs to exact match -# if not sd: -# date = int(os.stat(filename).st_ctime) -# -# try: -# fileData = self._fileManager.get_metadata(FileDestinations.SDCARD if sd else FileDestinations.LOCAL, filename) -# except: -# fileData = None -# if fileData is not None: -# if "analysis" in fileData: -# if estimatedPrintTime is None and "estimatedPrintTime" in fileData["analysis"]: -# estimatedPrintTime = fileData["analysis"]["estimatedPrintTime"] -# if "filament" in fileData["analysis"].keys(): -# filament = fileData["analysis"]["filament"] -# if "statistics" in fileData: -# printer_profile = self._printerProfileManager.get_current_or_default()["id"] -# if "averagePrintTime" in fileData["statistics"] and printer_profile in fileData["statistics"]["averagePrintTime"]: -# averagePrintTime = fileData["statistics"]["averagePrintTime"][printer_profile] -# if "lastPrintTime" in fileData["statistics"] and printer_profile in fileData["statistics"]["lastPrintTime"]: -# lastPrintTime = fileData["statistics"]["lastPrintTime"][printer_profile] -# -# if averagePrintTime is not None: -# self._selectedFile["estimatedPrintTime"] = averagePrintTime -# elif estimatedPrintTime is not None: -# # TODO apply factor which first needs to be tracked! -# self._selectedFile["estimatedPrintTime"] = estimatedPrintTime -# -# self._stateMonitor.setJobData({ -# "file": { -# "name": os.path.basename(filename) if filename is not None else None, -# "origin": FileDestinations.SDCARD if sd else FileDestinations.LOCAL, -# "size": filesize, -# "date": date -# }, -# "estimatedPrintTime": estimatedPrintTime, -# "averagePrintTime": averagePrintTime, -# "lastPrintTime": lastPrintTime, -# "filament": filament, -# }) -# -# def _sendInitialStateUpdate(self, callback): -# try: -# data = self._stateMonitor.getCurrentData() -# data.update({ -# "temps": list(self._temps), -# "logs": list(self._log), -# "messages": list(self._messages) -# }) -# callback.sendHistoryData(data) -# except Exception, err: -# import sys -# sys.stderr.write("ERROR: %s\n" % str(err)) -# pass -# -# def _getStateFlags(self): -# return { -# "operational": self.isOperational(), -# "locked": self.isLocked(), -# "printing": self.isPrinting(), -# "closedOrError": self.isClosedOrError(), -# "error": self.isError(), -# "paused": self.isPaused(), -# "ready": self.isReady(), -# "sdReady": self.isSdReady() -# } -# -# #~~ callbacks triggered from self._comm -# -# def mcLog(self, message): -# """ -# Callback method for the comm object, called upon log output. -# #""" -# self._addLog(message) -# -# def mcTempUpdate(self, temp, bedTemp): -# self._addTemperatureData(temp, bedTemp) -# -# def mcPosUpdate(self, MPos, WPos): -# self._addPositionData(MPos, WPos) -# -# def mcStateChange(self, state): -# """ -# Callback method for the comm object, called if the connection state changes. -# #""" -# oldState = self._state -# -# # forward relevant state changes to gcode manager -# if self._comm is not None and oldState == self._comm.STATE_PRINTING: -# if self._selectedFile is not None: -# if state == self._comm.STATE_OPERATIONAL: -# self._fileManager.log_print(FileDestinations.SDCARD if self._selectedFile["sd"] else FileDestinations.LOCAL, self._selectedFile["filename"], time.time(), self._comm.getPrintTime(), True, self._printerProfileManager.get_current_or_default()["id"]) -# elif state == self._comm.STATE_CLOSED or state == self._comm.STATE_ERROR or state == self._comm.STATE_CLOSED_WITH_ERROR: -# self._fileManager.log_print(FileDestinations.SDCARD if self._selectedFile["sd"] else FileDestinations.LOCAL, self._selectedFile["filename"], time.time(), self._comm.getPrintTime(), False, self._printerProfileManager.get_current_or_default()["id"]) -# self._analysisQueue.resume() # printing done, put those cpu cycles to good use -# elif self._comm is not None and state == self._comm.STATE_PRINTING: -# self._analysisQueue.pause() # do not analyse files while printing -# -# self._setState(state) -# -# def mcMessage(self, message): -# """ -# Callback method for the comm object, called upon message exchanges via serial. -# Stores the message in the message buffer, truncates buffer to the last 300 lines. -# #""" -# self._addMessage(message) -# -# def mcProgress(self): -# """ -# Callback method for the comm object, called upon any change in progress of the printjob. -# Triggers storage of new values for printTime, printTimeLeft and the current progress. -# #""" -# -# self._setProgressData(self._comm.getPrintProgress(), self._comm.getPrintFilepos(), self._comm.getPrintTime(), self._comm.getCleanedPrintTime()) -#======= """ Jogs the specified printer ``axis`` by the specified ``amount`` in mm. @@ -778,7 +376,6 @@ class PrinterInterface(object): def flow_rate(self, factor): """ Sets the ``factor`` for the printer's flow rate. -#>>>>>>> upstream/maintenance Arguments: factor (int, float): The factor for the flow rate to send to the firmware. Percentage expressed as either an @@ -1153,13 +750,7 @@ class PrinterCallback(object): # self._addTemperatureCallback(temperature) # self._changeEvent.set() # -# def setWorkPosition(self, workPosition): -# self._workPosition = workPosition -# self._changeEvent.set() -# -# def setMachinePosition(self, machinePosition): -# self._machinePosition = machinePosition -# self._changeEvent.set() + # # def addLog(self, log): # self._addLogCallback(log) diff --git a/src/octoprint/printer/standard.py b/src/octoprint/printer/standard.py index a652e6e7..e12c658e 100644 --- a/src/octoprint/printer/standard.py +++ b/src/octoprint/printer/standard.py @@ -22,7 +22,7 @@ from octoprint.plugin import plugin_manager, ProgressPlugin from octoprint.printer import PrinterInterface, PrinterCallback, UnknownScript from octoprint.printer.estimation import TimeEstimationHelper from octoprint.settings import settings -from octoprint.util import comm as comm +from octoprint.util import comm_acc as comm from octoprint.util import InvariantContainer @@ -256,6 +256,10 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): printer_profile = self._printerProfileManager.get_current_or_default() movement_speed = printer_profile["axes"][axis]["speed"] self.commands(["G91", "G1 %s%.4f F%d" % (axis.upper(), amount, movement_speed), "G90"]) +# def jog(self, axis, amount): +# printer_profile = self._printerProfileManager.get_current_or_default() +# movement_speed = printer_profile["axes"][axis]["speed"] +# self.commands(["G91", "G1 %s%.4f F%d" % (axis.upper(), amount, movement_speed), "G90", "?"]) def home(self, axes): if not isinstance(axes, (list, tuple)): @@ -846,6 +850,411 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): def on_comm_force_disconnect(self): self.disconnect() + def on_comm_pos_update(self, MPos, WPos): + self._add_position_data(MPos, WPos) + + def _add_position_data(self, MPos, WPos): + if MPos is None or WPos is None: + MPosString = WPosString = "-" + else: + MPosString = "X: %.4f Y: %.4f Z: %.4f" % ( MPos[0], MPos[1], MPos[2] ) + WPosString = "X: %.4f Y: %.4f Z: %.4f" % ( WPos[0], WPos[1], WPos[2] ) + + self._stateMonitor.setWorkPosition(WPosString) + self._stateMonitor.setMachinePosition(MPosString) + + + + #<<<<<<< HEAD + + +# +# def position(self, x, y): +# printer_profile = self._printerProfileManager.get_current_or_default() +# movement_speed = min(printer_profile["axes"]["x"]["speed"], printer_profile["axes"]["y"]["speed"]) +# self.commands(["G90", "G0 X%.3f Y%.3f F%d" % (x, y, movement_speed), "?"]) +# +# def home(self, axes): +# if(settings().getBoolean(["feature", "grbl"])): +# self.commands(["$H", "G92X0Y0Z0", "G90", "G21"]) +# else: +# self.commands(["G91", "G28 %s" % " ".join(map(lambda x: "%s0" % x.upper(), axes)), "G90"]) +# +# def extrude(self, amount): +# printer_profile = self._printerProfileManager.get_current_or_default() +# extrusion_speed = printer_profile["axes"]["e"]["speed"] +# self.commands(["G91", "G1 E%s F%d" % (amount, extrusion_speed), "G90"]) +# +# def changeTool(self, tool): +# try: +# toolNum = int(tool[len("tool"):]) +# self.command("T%d" % toolNum) +# except ValueError: +# pass +# +# def setTemperature(self, type, value): +# if type.startswith("tool"): +# printer_profile = self._printerProfileManager.get_current_or_default() +# extruder_count = printer_profile["extruder"]["count"] +# if extruder_count > 1: +# try: +# toolNum = int(type[len("tool"):]) +# self.command("M104 T%d S%f" % (toolNum, value)) +# except ValueError: +# pass +# else: +# self.command("M104 S%f" % value) +# elif type == "bed": +# self.command("M140 S%f" % value) +# +# def setTemperatureOffset(self, offsets={}): +# if self._comm is None: +# return +# +# tool, bed = self._comm.getOffsets() +# +# validatedOffsets = {} +# +# for key in offsets: +# value = offsets[key] +# if key == "bed": +# bed = value +# validatedOffsets[key] = value +# elif key.startswith("tool"): +# try: +# toolNum = int(key[len("tool"):]) +# tool[toolNum] = value +# validatedOffsets[key] = value +# except ValueError: +# pass +# +# self._comm.setTemperatureOffset(tool, bed) +# self._stateMonitor.setTempOffsets(validatedOffsets) +# +# def selectFile(self, filename, sd, printAfterSelect=False): +# if self._comm is None or (self._comm.isBusy() or self._comm.isStreaming()): +# self._logger.info("Cannot load file: printer not connected or currently busy") +# return +# +# self._printAfterSelect = printAfterSelect +# self._comm.selectFile(filename, sd) +# self._setProgressData(0, None, None, None) +# self._setCurrentZ(None) +# +# def unselectFile(self): +# if self._comm is not None and (self._comm.isBusy() or self._comm.isStreaming()): +# return +# +# self._comm.unselectFile() +# self._setProgressData(0, None, None, None) +# self._setCurrentZ(None) +# +# def startPrint(self): +# """ +# Starts the currently loaded print job. +# Only starts if the printer is connected and operational, not currently printing and a printjob is loaded +# """ +# if self._comm is None or not self._comm.isOperational() or self._comm.isPrinting(): +# return +# if self._selectedFile is None: +# return +# +# self._timeEstimationData = TimeEstimationHelper() +# self._lastProgressReport = None +# self._setCurrentZ(None) +# self._comm.startPrint() +# self._addPositionData(None, None) +# + +# +# def togglePausePrint(self): +# """ +# Pause the current printjob. +# """ +# if self._comm is None: +# return +# +# self._comm.setPause(not self._comm.isPaused()) +# +# def cancelPrint(self, disableMotorsAndHeater=True): +# """ +# Cancel the current printjob. +# """ +# if self._comm is None: +# return +# +# self._comm.cancelPrint() +# +# if disableMotorsAndHeater: +# printer_profile = self._printerProfileManager.get_current_or_default() +# extruder_count = printer_profile["extruder"]["count"] +# +# # disable motors, switch off hotends, bed and fan +# #commands = ["M84"] +# #commands.extend(map(lambda x: "M104 T%d S0" % x, range(extruder_count))) +# #commands.extend(["M140 S0", "M106 S0"]) +# commands = ["M05", "G0X0Y0", "M09"] +# self.commands(commands) +# +# # reset progress, height, print time +# self._setCurrentZ(None) +# self._setProgressData(None, None, None, None) +# +# # mark print as failure +# if self._selectedFile is not None: +# self._fileManager.log_print(FileDestinations.SDCARD if self._selectedFile["sd"] else FileDestinations.LOCAL, self._selectedFile["filename"], time.time(), self._comm.getPrintTime(), False, self._printerProfileManager.get_current_or_default()["id"]) +# payload = { +# "file": self._selectedFile["filename"], +# "origin": FileDestinations.LOCAL +# } +# if self._selectedFile["sd"]: +# payload["origin"] = FileDestinations.SDCARD +# eventManager().fire(Events.PRINT_FAILED, payload) +# +# #~~ state monitoring +# +# def _setCurrentZ(self, currentZ): +# self._currentZ = currentZ +# self._stateMonitor.setCurrentZ(self._currentZ) +# +# def _setState(self, state): +# self._state = state +# self._stateMonitor.setState({"text": self.getStateString(), "flags": self._getStateFlags()}) +# +# def _addLog(self, log): +# self._log.append(log) +# self._stateMonitor.addLog(log) +# +# def _addMessage(self, message): +# self._messages.append(message) +# self._stateMonitor.addMessage(message) +# +# def _estimateTotalPrintTime(self, progress, printTime): +# if not progress or not printTime or not self._timeEstimationData: +# #self._estimationLogger.info("{progress};{printTime};;;;".format(**locals())) +# return None +# +# else: +# newEstimate = printTime / progress +# self._timeEstimationData.update(newEstimate) +# +# result = None +# if self._timeEstimationData.is_stable(): +# result = self._timeEstimationData.average_total_rolling +# +# #averageTotal = self._timeEstimationData.average_total +# #averageTotalRolling = self._timeEstimationData.average_total_rolling +# #averageDistance = self._timeEstimationData.average_distance +# +# #self._estimationLogger.info("{progress};{printTime};{newEstimate};{averageTotal};{averageTotalRolling};{averageDistance}".format(**locals())) +# +# return result +# +# def _setProgressData(self, progress, filepos, printTime, cleanedPrintTime): +# estimatedTotalPrintTime = self._estimateTotalPrintTime(progress, cleanedPrintTime) +# statisticalTotalPrintTime = None +# totalPrintTime = estimatedTotalPrintTime +# +# if self._selectedFile and "estimatedPrintTime" in self._selectedFile and self._selectedFile["estimatedPrintTime"]: +# statisticalTotalPrintTime = self._selectedFile["estimatedPrintTime"] +# if progress and cleanedPrintTime: +# if estimatedTotalPrintTime is None: +# totalPrintTime = statisticalTotalPrintTime +# else: +# if progress < 0.5: +# sub_progress = progress * 2 +# else: +# sub_progress = 1.0 +# totalPrintTime = (1 - sub_progress) * statisticalTotalPrintTime + sub_progress * estimatedTotalPrintTime +# +# #self._printTimeLogger.info("{progress};{cleanedPrintTime};{estimatedTotalPrintTime};{statisticalTotalPrintTime};{totalPrintTime}".format(**locals())) +# +# self._progress = progress +# self._printTime = printTime +# self._printTimeLeft = totalPrintTime - cleanedPrintTime if (totalPrintTime is not None and cleanedPrintTime is not None) else None +# +# self._stateMonitor.setProgress({ +# "completion": self._progress * 100 if self._progress is not None else None, +# "filepos": filepos, +# "printTime": int(self._printTime) if self._printTime is not None else None, +# "printTimeLeft": int(self._printTimeLeft) if self._printTimeLeft is not None else None +# }) +# +# if progress: +# progress_int = int(progress * 100) +# if self._lastProgressReport != progress_int: +# self._lastProgressReport = progress_int +# self._reportPrintProgressToPlugins(progress_int) +# +# +# def _addTemperatureData(self, temp, bedTemp): +# currentTimeUtc = int(time.time()) +# +# data = { +# "time": currentTimeUtc +# } +# for tool in temp.keys(): +# data["tool%d" % tool] = { +# "actual": temp[tool][0], +# "target": temp[tool][1] +# } +# if bedTemp is not None and isinstance(bedTemp, tuple): +# data["bed"] = { +# "actual": bedTemp[0], +# "target": bedTemp[1] +# } +# +# self._temps.append(data) +# +# self._temp = temp +# self._bedTemp = bedTemp +# +# self._stateMonitor.addTemperature(data) +# +# def _setJobData(self, filename, filesize, sd): +# if filename is not None: +# self._selectedFile = { +# "filename": filename, +# "filesize": filesize, +# "sd": sd, +# "estimatedPrintTime": None +# } +# else: +# self._selectedFile = None +# self._stateMonitor.setJobData({ +# "file": { +# "name": None, +# "origin": None, +# "size": None, +# "date": None +# }, +# "estimatedPrintTime": None, +# "averagePrintTime": None, +# "lastPrintTime": None, +# "filament": None, +# }) +# return +# +# estimatedPrintTime = None +# lastPrintTime = None +# averagePrintTime = None +# date = None +# filament = None +# if filename: +# # Use a string for mtime because it could be float and the +# # javascript needs to exact match +# if not sd: +# date = int(os.stat(filename).st_ctime) +# +# try: +# fileData = self._fileManager.get_metadata(FileDestinations.SDCARD if sd else FileDestinations.LOCAL, filename) +# except: +# fileData = None +# if fileData is not None: +# if "analysis" in fileData: +# if estimatedPrintTime is None and "estimatedPrintTime" in fileData["analysis"]: +# estimatedPrintTime = fileData["analysis"]["estimatedPrintTime"] +# if "filament" in fileData["analysis"].keys(): +# filament = fileData["analysis"]["filament"] +# if "statistics" in fileData: +# printer_profile = self._printerProfileManager.get_current_or_default()["id"] +# if "averagePrintTime" in fileData["statistics"] and printer_profile in fileData["statistics"]["averagePrintTime"]: +# averagePrintTime = fileData["statistics"]["averagePrintTime"][printer_profile] +# if "lastPrintTime" in fileData["statistics"] and printer_profile in fileData["statistics"]["lastPrintTime"]: +# lastPrintTime = fileData["statistics"]["lastPrintTime"][printer_profile] +# +# if averagePrintTime is not None: +# self._selectedFile["estimatedPrintTime"] = averagePrintTime +# elif estimatedPrintTime is not None: +# # TODO apply factor which first needs to be tracked! +# self._selectedFile["estimatedPrintTime"] = estimatedPrintTime +# +# self._stateMonitor.setJobData({ +# "file": { +# "name": os.path.basename(filename) if filename is not None else None, +# "origin": FileDestinations.SDCARD if sd else FileDestinations.LOCAL, +# "size": filesize, +# "date": date +# }, +# "estimatedPrintTime": estimatedPrintTime, +# "averagePrintTime": averagePrintTime, +# "lastPrintTime": lastPrintTime, +# "filament": filament, +# }) +# +# def _sendInitialStateUpdate(self, callback): +# try: +# data = self._stateMonitor.getCurrentData() +# data.update({ +# "temps": list(self._temps), +# "logs": list(self._log), +# "messages": list(self._messages) +# }) +# callback.sendHistoryData(data) +# except Exception, err: +# import sys +# sys.stderr.write("ERROR: %s\n" % str(err)) +# pass +# +# def _getStateFlags(self): +# return { +# "operational": self.isOperational(), +# "locked": self.isLocked(), +# "printing": self.isPrinting(), +# "closedOrError": self.isClosedOrError(), +# "error": self.isError(), +# "paused": self.isPaused(), +# "ready": self.isReady(), +# "sdReady": self.isSdReady() +# } +# +# #~~ callbacks triggered from self._comm +# +# def mcLog(self, message): +# """ +# Callback method for the comm object, called upon log output. +# #""" +# self._addLog(message) +# +# def mcTempUpdate(self, temp, bedTemp): +# self._addTemperatureData(temp, bedTemp) +# + +# +# def mcStateChange(self, state): +# """ +# Callback method for the comm object, called if the connection state changes. +# #""" +# oldState = self._state +# +# # forward relevant state changes to gcode manager +# if self._comm is not None and oldState == self._comm.STATE_PRINTING: +# if self._selectedFile is not None: +# if state == self._comm.STATE_OPERATIONAL: +# self._fileManager.log_print(FileDestinations.SDCARD if self._selectedFile["sd"] else FileDestinations.LOCAL, self._selectedFile["filename"], time.time(), self._comm.getPrintTime(), True, self._printerProfileManager.get_current_or_default()["id"]) +# elif state == self._comm.STATE_CLOSED or state == self._comm.STATE_ERROR or state == self._comm.STATE_CLOSED_WITH_ERROR: +# self._fileManager.log_print(FileDestinations.SDCARD if self._selectedFile["sd"] else FileDestinations.LOCAL, self._selectedFile["filename"], time.time(), self._comm.getPrintTime(), False, self._printerProfileManager.get_current_or_default()["id"]) +# self._analysisQueue.resume() # printing done, put those cpu cycles to good use +# elif self._comm is not None and state == self._comm.STATE_PRINTING: +# self._analysisQueue.pause() # do not analyse files while printing +# +# self._setState(state) +# +# def mcMessage(self, message): +# """ +# Callback method for the comm object, called upon message exchanges via serial. +# Stores the message in the message buffer, truncates buffer to the last 300 lines. +# #""" +# self._addMessage(message) +# +# def mcProgress(self): +# """ +# Callback method for the comm object, called upon any change in progress of the printjob. +# Triggers storage of new values for printTime, printTimeLeft and the current progress. +# #""" +# +# self._setProgressData(self._comm.getPrintProgress(), self._comm.getPrintFilepos(), self._comm.getPrintTime(), self._comm.getCleanedPrintTime()) +#======= class StateMonitor(object): def __init__(self, interval=0.5, on_update=None, on_add_temperature=None, on_add_log=None, on_add_message=None): @@ -861,7 +1270,9 @@ class StateMonitor(object): self._sd_upload_data = None self._current_z = None self._progress = None - + self._machinePosition = None + self._workPosition = None + self._offsets = {} self._change_event = threading.Event() @@ -877,6 +1288,8 @@ class StateMonitor(object): self.set_job_data(job_data) self.set_progress(progress) self.set_current_z(current_z) + self._machinePosition = None + self._workPosition = None def add_temperature(self, temperature): self._on_add_temperature(temperature) @@ -935,6 +1348,14 @@ class StateMonitor(object): "progress": self._progress, "offsets": self._offsets } + + def setWorkPosition(self, workPosition): + self._workPosition = workPosition + self._change_event.set() + + def setMachinePosition(self, machinePosition): + self._machinePosition = machinePosition + self._change_event.set() class TemperatureHistory(InvariantContainer): diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py index 8abba926..8f53006c 100644 --- a/src/octoprint/server/util/flask.py +++ b/src/octoprint/server/util/flask.py @@ -478,9 +478,6 @@ class PluginAssetResolver(flask.ext.assets.FlaskResolver): try: prefix, plugin, name = item.split("/", 2) blueprint = prefix + "." + plugin - print('####', blueprint, app.blueprints[blueprint]) - #for attr in dir(app.blueprints[blueprint]): - # print "obj.%s = %s" % (attr, getattr(app.blueprints[blueprint], attr)) directory = flask.ext.assets.get_static_folder(app.blueprints[blueprint]) item = name endpoint = blueprint + ".static" diff --git a/src/octoprint/static/js/app/viewmodels/connection.js b/src/octoprint/static/js/app/viewmodels/connection.js index d6408dbf..62ab6622 100644 --- a/src/octoprint/static/js/app/viewmodels/connection.js +++ b/src/octoprint/static/js/app/viewmodels/connection.js @@ -211,7 +211,7 @@ $(function() { self.isReady(data.flags.ready); self.isLoading(data.flags.loading); - var connectionTab = $("#connection"); + var connectionTab = $("#connection_wrapper"); if (self.previousIsOperational != self.isOperational()) { if (self.isOperational() && connectionTab.hasClass("in")) { // connection just got established, close connection tab for now diff --git a/src/octoprint/static/js/app/viewmodels/control.js b/src/octoprint/static/js/app/viewmodels/control.js index 962ee910..a9ea5249 100644 --- a/src/octoprint/static/js/app/viewmodels/control.js +++ b/src/octoprint/static/js/app/viewmodels/control.js @@ -2,9 +2,6 @@ //function ControlViewModel(loginStateViewModel, settingsViewModel, printerStateViewModel) { // var self = this; // -// self.loginState = loginStateViewModel; -// self.settings = settingsViewModel; -// self.printerState = printerStateViewModel; // // self._createToolEntry = function() { // return { @@ -23,7 +20,6 @@ // self.isLoading = ko.observable(undefined); // // self.extrusionAmount = ko.observable(undefined); -// self.jogDistanceInMM = ko.observable(undefined) // self.controls = ko.observableArray([]); // // self.tools = ko.observableArray([]); @@ -60,6 +56,7 @@ $(function() { self.loginState = parameters[0]; self.settings = parameters[1]; + self.printerState = parameters[2]; self._createToolEntry = function () { return { @@ -207,14 +204,7 @@ $(function() { // return control; // }; // -// self.laserPos = ko.computed(function(){ -// var pos = self.printerState.currentPos(); -// if(!pos){ -// return "(?, ?)"; -// } else { -// return "("+ pos.x + ", "+ pos.y + ")"; -// } -// }, this); + // // self.focus_on = function(){ // @@ -399,9 +389,7 @@ $(function() { // }); // }; // -// self.setCoordinateOrigin = function(){ -// self.sendCustomCommand({type:'command', command: "G92 X0 Y0"}); -// }; + //======= self.sendJogCommand = function (axis, multiplier, distance) { if (typeof distance === "undefined") @@ -864,12 +852,26 @@ $(function() { button.click(); } }; + self.laserPos = ko.computed(function () { + var pos = self.printerState.currentPos(); + if (!pos) { + return "(?, ?)"; + } else { + return "(" + pos.x + ", " + pos.y + ")"; + } + }, this); + + self.setCoordinateOrigin = function () { + self.sendCustomCommand({type: 'command', command: "G92 X0 Y0"}); + }; + + self.jogDistanceInMM = ko.observable(undefined) } OCTOPRINT_VIEWMODELS.push([ ControlViewModel, - ["loginStateViewModel", "settingsViewModel"], + ["loginStateViewModel", "settingsViewModel", 'printerStateViewModel'], "#control" ]); }); diff --git a/src/octoprint/static/js/app/viewmodels/files.js b/src/octoprint/static/js/app/viewmodels/files.js index 6d096b80..65263475 100644 --- a/src/octoprint/static/js/app/viewmodels/files.js +++ b/src/octoprint/static/js/app/viewmodels/files.js @@ -347,10 +347,14 @@ $(function() { return data["prints"]["last"]["success"] ? "text-success" : "text-error"; }; - self.templateFor = function(data) { - return "files_template_" + data.type; - }; - + self.templateFor = function(data) { + var extension = data.name.split('.').pop().toLowerCase(); + if (extension === "svg") { + return "files_template_" + data.type + "_svg"; + } else { + return "files_template_" + data.type; + } + }; self.getEntryId = function(data) { return "gcode_file_" + md5(data["origin"] + ":" + data["name"]); }; diff --git a/src/octoprint/static/js/app/viewmodels/printerstate.js b/src/octoprint/static/js/app/viewmodels/printerstate.js index 19da04f1..fde3aa79 100644 --- a/src/octoprint/static/js/app/viewmodels/printerstate.js +++ b/src/octoprint/static/js/app/viewmodels/printerstate.js @@ -7,7 +7,6 @@ // self.stateString = ko.observable(undefined); // self.isErrorOrClosed = ko.observable(undefined); // self.isOperational = ko.observable(undefined); -// self.isLocked = ko.observable(undefined); // self.isConnecting = ko.observable(undefined); // self.isPrinting = ko.observable(undefined); // self.isPaused = ko.observable(undefined); @@ -33,7 +32,6 @@ // // self.currentHeight = ko.observable(undefined); // -// self.currentPos = ko.observable(undefined); // self.conversion = vectorConversionViewModel; // // @@ -70,6 +68,8 @@ $(function() { self.isReady = ko.observable(undefined); self.isLoading = ko.observable(undefined); self.isSdReady = ko.observable(undefined); + self.isLocked = ko.observable(undefined); + self.isConnecting = ko.observable(undefined); self.filename = ko.observable(undefined); self.progress = ko.observable(undefined); @@ -87,6 +87,7 @@ $(function() { self.lastPrintTime = ko.observable(undefined); self.currentHeight = ko.observable(undefined); + self.currentPos = ko.observable(undefined); self.TITLE_PRINT_BUTTON_PAUSED = gettext("Restarts the print job from the beginning"); self.TITLE_PRINT_BUTTON_UNPAUSED = gettext("Starts the print job"); @@ -190,7 +191,6 @@ $(function() { // self.stateString(gettext(data.text)); // self.isErrorOrClosed(data.flags.closedOrError); // self.isOperational(data.flags.operational); -// self.isLocked(data.flags.locked); // self.isConnecting(data.text === "Connecting" || data.text === "Opening serial port"); // self.isPaused(data.flags.paused); // self.isPrinting(data.flags.printing); @@ -274,6 +274,8 @@ $(function() { self.isError(data.flags.error); self.isReady(data.flags.ready); self.isSdReady(data.flags.sdReady); + self.isLocked(data.flags.locked); + self.isConnecting(data.text === "Connecting" || data.text === "Opening serial port"); if (self.isPaused() != prevPaused) { if (self.isPaused()) { diff --git a/src/octoprint/static/js/app/viewmodels/settings.js b/src/octoprint/static/js/app/viewmodels/settings.js index 5eed7d6c..d204d794 100644 --- a/src/octoprint/static/js/app/viewmodels/settings.js +++ b/src/octoprint/static/js/app/viewmodels/settings.js @@ -119,15 +119,7 @@ // self.requestData(); // }; // -// self.saveall = function(e, v){ -//// $("#settings_save_btn").css("visibility", "visible"); -// -// $("#settingsTabs li.active").addClass('saveInProgress'); -// if(self.savetimer !== undefined){ -// clearTimeout(self.savetimer); -// } -// self.savetimer = setTimeout(self.instantSaveData, 2000); -// }; + // // self.requestData = function(callback) { // $.ajax({ @@ -202,68 +194,7 @@ // self.terminalFilters(response.terminalFilters); // }; // -// self.collectData = function (){ -// var data = ko.mapping.toJS(self.settings); -// data = _.extend(data, { -// "api" : { -// "enabled": self.api_enabled(), -// "key": self.api_key(), -// "allowCrossOrigin": self.api_allowCrossOrigin() -// }, -// "appearance" : { -// "name": self.appearance_name(), -// "color": self.appearance_color() -// }, -// "printer": { -// "defaultExtrusionLength": self.printer_defaultExtrusionLength() -// }, -// "webcam": { -// "streamUrl": self.webcam_streamUrl(), -// "snapshotUrl": self.webcam_snapshotUrl(), -// "ffmpegPath": self.webcam_ffmpegPath(), -// "bitrate": self.webcam_bitrate(), -// "watermark": self.webcam_watermark(), -// "flipH": self.webcam_flipH(), -// "flipV": self.webcam_flipV() -// }, -// "feature": { -// "gcodeViewer": self.feature_gcodeViewer(), -// "temperatureGraph": self.feature_temperatureGraph(), -// "waitForStart": self.feature_waitForStart(), -// "alwaysSendChecksum": self.feature_alwaysSendChecksum(), -// "sdSupport": self.feature_sdSupport(), -// "sdAlwaysAvailable": self.feature_sdAlwaysAvailable(), -// "swallowOkAfterResend": self.feature_swallowOkAfterResend(), -// "repetierTargetTemp": self.feature_repetierTargetTemp(), -// "keyboardControl": self.feature_keyboardControl() -// }, -// "serial": { -// "port": self.serial_port(), -// "baudrate": self.serial_baudrate(), -// "autoconnect": self.serial_autoconnect(), -// "timeoutConnection": self.serial_timeoutConnection(), -// "timeoutDetection": self.serial_timeoutDetection(), -// "timeoutCommunication": self.serial_timeoutCommunication(), -// "timeoutTemperature": self.serial_timeoutTemperature(), -// "timeoutSdStatus": self.serial_timeoutSdStatus(), -// "log": self.serial_log() -// }, -// "folder": { -// "uploads": self.folder_uploads(), -// "timelapse": self.folder_timelapse(), -// "timelapseTmp": self.folder_timelapseTmp(), -// "logs": self.folder_logs(), -// "watched": self.folder_watched() -// }, -// "temperature": { -// "profiles": self.temperature_profiles() -// }, -// "system": { -// "actions": self.system_actions() -// } -// }); -// return data; -// }; + //======= $(function() { function SettingsViewModel(parameters) { @@ -591,8 +522,7 @@ $(function() { self.languagePacksAvailable = ko.computed(function() { return self.translations.allSize() > 0; }); - - }; + //<<<<<<< HEAD // self.saveData = function() { @@ -615,23 +545,7 @@ $(function() { // }); // }; // -// self.instantSaveData = function() { -// -// var data = self.collectData(); -// -// $.ajax({ -// url: API_BASEURL + "settings", -// type: "POST", -// dataType: "json", -// contentType: "application/json; charset=UTF-8", -// data: JSON.stringify(data), -// success: function(response) { -//// self.fromResponse(response); -//// $("#settings_dialog").modal("hide"); -//// $("#settings_save_btn").attr("disabled", "disabled"); -//// $("#settings_save_btn").css("visibility", "hidden"); -// $("#settingsTabs li.active").removeClass('saveInProgress'); -// self.savetimer = undefined; + //======= self.deleteLanguagePack = function(locale, pack) { $.ajax({ @@ -821,7 +735,102 @@ $(function() { } }); }; -// } + + self.saveall = function(e, v){ + // $("#settings_save_btn").css("visibility", "visible"); + + $("#settingsTabs li.active").addClass('saveInProgress'); + if(self.savetimer !== undefined){ + clearTimeout(self.savetimer); + } + self.savetimer = setTimeout(self.instantSaveData, 2000); + }; + + self.instantSaveData = function() { + + var data = self.collectData(); + + $.ajax({ + url: API_BASEURL + "settings", + type: "POST", + dataType: "json", + contentType: "application/json; charset=UTF-8", + data: JSON.stringify(data), + success: function(response) { + // self.fromResponse(response); + // $("#settings_dialog").modal("hide"); + // $("#settings_save_btn").attr("disabled", "disabled"); + // $("#settings_save_btn").css("visibility", "hidden"); + $("#settingsTabs li.active").removeClass('saveInProgress'); + self.savetimer = undefined; + } + }); + }; + + + self.collectData = function (){ + var data = ko.mapping.toJS(self.settings); + data = _.extend(data, { + "api" : { + "enabled": self.api_enabled(), + "key": self.api_key(), + "allowCrossOrigin": self.api_allowCrossOrigin() + }, + "appearance" : { + "name": self.appearance_name(), + "color": self.appearance_color() + }, + "printer": { + "defaultExtrusionLength": self.printer_defaultExtrusionLength() + }, + "webcam": { + "streamUrl": self.webcam_streamUrl(), + "snapshotUrl": self.webcam_snapshotUrl(), + "ffmpegPath": self.webcam_ffmpegPath(), + "bitrate": self.webcam_bitrate(), + "watermark": self.webcam_watermark(), + "flipH": self.webcam_flipH(), + "flipV": self.webcam_flipV() + }, + "feature": { + "gcodeViewer": self.feature_gcodeViewer(), + "temperatureGraph": self.feature_temperatureGraph(), + "waitForStart": self.feature_waitForStart(), + "alwaysSendChecksum": self.feature_alwaysSendChecksum(), + "sdSupport": self.feature_sdSupport(), + "sdAlwaysAvailable": self.feature_sdAlwaysAvailable(), + "swallowOkAfterResend": self.feature_swallowOkAfterResend(), + "repetierTargetTemp": self.feature_repetierTargetTemp(), + "keyboardControl": self.feature_keyboardControl() + }, + "serial": { + "port": self.serial_port(), + "baudrate": self.serial_baudrate(), + "autoconnect": self.serial_autoconnect(), + "timeoutConnection": self.serial_timeoutConnection(), + "timeoutDetection": self.serial_timeoutDetection(), + "timeoutCommunication": self.serial_timeoutCommunication(), + "timeoutTemperature": self.serial_timeoutTemperature(), + "timeoutSdStatus": self.serial_timeoutSdStatus(), + "log": self.serial_log() + }, + "folder": { + "uploads": self.folder_uploads(), + "timelapse": self.folder_timelapse(), + "timelapseTmp": self.folder_timelapseTmp(), + "logs": self.folder_logs(), + "watched": self.folder_watched() + }, + "temperature": { + "profiles": self.temperature_profiles() + }, + "system": { + "actions": self.system_actions() + } + }); + return data; + }; + }; OCTOPRINT_VIEWMODELS.push([ SettingsViewModel, diff --git a/src/octoprint/static/js/app/viewmodels/terminal.js b/src/octoprint/static/js/app/viewmodels/terminal.js index 6099cf1a..8e0766ed 100644 --- a/src/octoprint/static/js/app/viewmodels/terminal.js +++ b/src/octoprint/static/js/app/viewmodels/terminal.js @@ -11,7 +11,6 @@ // // self.isErrorOrClosed = ko.observable(undefined); // self.isOperational = ko.observable(undefined); -// self.isLocked = ko.observable(undefined); // self.isPrinting = ko.observable(undefined); // self.isPaused = ko.observable(undefined); // self.isError = ko.observable(undefined); @@ -93,32 +92,7 @@ // } // }; // -// self.sendCommandWithSafetyPopup = function(){ -// var command = self.command().split(' ').join(''); -// if (!command) { -// return; -// } -// -// console.log(command); -// var parts = command.match(/^(M3|M03)(S[0-9.]+)?/i); -// if(parts !== null){ -// -// $("#confirmation_dialog .confirmation_dialog_message").text(gettext("The laser will now be enabled. Protect yourself and everybody in the room appropriately before proceeding!")); -// $("#confirmation_dialog .confirmation_dialog_acknowledge").unbind("click"); -// $("#confirmation_dialog .confirmation_dialog_acknowledge").click( -// function(e) { -// e.preventDefault(); -// $("#confirmation_dialog").modal("hide"); -// self.sendCommand(); -// }); -// $("#confirmation_dialog").modal("show"); -// -// -// -// } else { -// self.sendCommand(); -// } -// }; + // // self.sendCommand = function() { // var command = self.command(); @@ -154,6 +128,7 @@ $(function() { self.isError = ko.observable(undefined); self.isReady = ko.observable(undefined); self.isLoading = ko.observable(undefined); + self.isLocked = ko.observable(undefined); self.autoscrollEnabled = ko.observable(true); @@ -370,6 +345,33 @@ $(function() { }; //>>>>>>> upstream/maintenance + self.sendCommandWithSafetyPopup = function () { + var command = self.command().split(' ').join(''); + if (!command) { + return; + } + + console.log(command); + var parts = command.match(/^(M3|M03)(S[0-9.]+)?/i); + if (parts !== null) { + + $("#confirmation_dialog .confirmation_dialog_message").text(gettext("The laser will now be enabled. Protect yourself and everybody in the room appropriately before proceeding!")); + $("#confirmation_dialog .confirmation_dialog_acknowledge").unbind("click"); + $("#confirmation_dialog .confirmation_dialog_acknowledge").click( + function (e) { + e.preventDefault(); + $("#confirmation_dialog").modal("hide"); + self.sendCommand(); + }); + $("#confirmation_dialog").modal("show"); + + + + } else { + self.sendCommand(); + } + }; + } OCTOPRINT_VIEWMODELS.push([ diff --git a/src/octoprint/templates/mrbeam_index.jinja2 b/src/octoprint/templates/mrbeam_index.jinja2 index e16a081f..65cd06ed 100644 --- a/src/octoprint/templates/mrbeam_index.jinja2 +++ b/src/octoprint/templates/mrbeam_index.jinja2 @@ -19,13 +19,15 @@ Mr Beam Logo + @@ -116,7 +119,7 @@ -
+
@@ -131,7 +134,8 @@
-
+ +
{{ _('Machine State') }}:
@@ -460,9 +464,9 @@
-
+
-
+
@@ -617,20 +621,21 @@ - - {% if templatePlugins %} - {% for plugin_name in templatePlugins %} - {% include plugin_name+".jinja2" ignore missing %} - {% endfor %} - {% endif %} - + + {% if templatePlugins %} + {% for plugin_name in templatePlugins %} + {% include plugin_name+".jinja2" ignore missing %} + {% endfor %} + {% endif %} + - + {% include 'dialogs/confirmation.jinja2' %} {% include 'dialogs/firstrun.jinja2' %} {#% include 'dialogs/settings.jinja2' %#} {% include 'dialogs/slicing.jinja2' %} + {% include 'dialogs/usersettings.jinja2' %} diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index dc2cf448..c6c1af1f 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -446,11 +446,6 @@ class MachineCom(object): return if self.isPrinting() and not self.isSdFileSelected(): -#<<<<<<< HEAD -# self._commandQueue.put(cmd) -# elif self.isOperational() or self.isLocked(): -# self._sendCommand(cmd) -#======= self._commandQueue.put((cmd, cmd_type)) elif self.isOperational(): self._sendCommand(cmd, cmd_type=cmd_type) @@ -506,7 +501,6 @@ class MachineCom(object): for line in scriptLines: self.sendCommand(line) return "\n".join(scriptLines) -#>>>>>>> upstream/maintenance def startPrint(self): if not self.isOperational() or self.isPrinting(): @@ -833,10 +827,6 @@ class MachineCom(object): startSeen = False supportRepetierTargetTemp = settings().getBoolean(["feature", "repetierTargetTemp"]) -#<<<<<<< HEAD -# grblMoving = True -# grblLastStatus = "" -#======= supportWait = settings().getBoolean(["feature", "supportWait"]) connection_timeout = settings().getFloat(["serial", "timeout", "connection"]) @@ -846,7 +836,6 @@ class MachineCom(object): if try_hello: self._sendCommand("M110") self._clear_to_send.set() -#>>>>>>> upstream/maintenance while self._monitoring_active: try: @@ -951,76 +940,11 @@ class MachineCom(object): except ValueError: pass -#<<<<<<< HEAD -# # GRBL Position update -# if self._grbl : -# if 'MPos:' in line: -# -# if grblLastStatus == line: -# grblMoving = False -# else: -# grblMoving = True -# -# grblLastStatus = line -# -# if("Alarm" in line): -# self._changeState(self.STATE_LOCKED) -# if("Idle" in line and self._state == self.STATE_LOCKED): -# self._changeState(self.STATE_OPERATIONAL) -# -# -# parts = line.strip("\r\n").split(":") -# -# pos = parts[1].split(",") -# MPos = (float(pos[0]), float(pos[1]), float(pos[2])) -# -# pos = parts[2].split(",") -# WPos = (float(pos[0]), float(pos[1]), float( pos[2].strip(">") )) -# -# self._callback.mcPosUpdate(MPos, WPos) -# -# if("ALARM: Hard/soft limit" in line): -# errorMsg = "Machine Limit Hit. Please reset the machine and do a homing cycle" -# self._log(errorMsg) -# self._errorValue = errorMsg -# self._changeState(self.STATE_ERROR) -# eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) -# self.close() -# -# if("Invalid gcode" in line and self._state == self.STATE_PRINTING): -# errorMsg = line -# self._log(errorMsg) -# self._errorValue = errorMsg -# self._changeState(self.STATE_ERROR) -# eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) -# -# if("error:" in line and self._state == self.STATE_PRINTING): -# errorMsg = line -# self._log(errorMsg) -# self._errorValue = errorMsg -# self._changeState(self.STATE_ERROR) -# eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) -# -# if("[" in line): -# versionMatch = re.search("\[(?P.+)\.(?P[0-9a-f]{7})(?P-dirty)?:(?P.*)\]", line) -# if(versionMatch): -# # write grbl version to file -# versionDict = versionMatch.groupdict() -# if versionDict['dirty'] == '-dirty': -# versionDict['dirty'] = True -# versionDict['lastConnect'] = time.time() -# import yaml -# versionFile = os.path.join(settings().getBaseFolder("logs"),'grbl_version.yml') -# with open(versionFile, 'w') as outfile: -# outfile.write( yaml.dump(versionDict, default_flow_style=True) ) -# logging.info("updated firmware version file " + versionFile) -#======= #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 'ok' in line and self._heatupWaitStartTime: self._heatupWaitTimeLost = self._heatupWaitTimeLost + (time.time() - self._heatupWaitStartTime) self._heatupWaitStartTime = None self._heating = False -#>>>>>>> upstream/maintenance ##~~ SD Card handling elif 'SD init fail' in line or 'volume.init failed' in line or 'openRoot failed' in line: @@ -1129,22 +1053,12 @@ class MachineCom(object): self._baudrateDetectRetry -= 1 self._serial.write('\n') self._log("Baudrate test retry: %d" % (self._baudrateDetectRetry)) -#<<<<<<< HEAD -# # self._sendCommand("M105") -# if self._grbl: -# self._sendCommand("$") -# else: -# self._sendCommand("M105") -# self._testingBaudrate = True -# else: -#======= if self._grbl: self._sendCommand("$") else: self._sendCommand("M110") self._clear_to_send.set() elif len(self._baudrateDetectList) > 0: -#>>>>>>> upstream/maintenance baudrate = self._baudrateDetectList.pop(0) try: self._serial.baudrate = baudrate @@ -1154,24 +1068,6 @@ class MachineCom(object): self._baudrateDetectRetry = 5 self._timeout = get_new_timeout("communication") self._serial.write('\n') -#<<<<<<< HEAD -# # self._sendCommand("M105") -# if self._grbl: -# self._sendCommand("$") -# else: -# self._sendCommand("M105") -# self._testingBaudrate = True -# except: -# self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, getExceptionString())) -# elif self._grbl and '$$' in line: -# self._log("Baudrate test ok: %d" % (self._baudrateDetectTestOk)) -# self._changeState(self.STATE_OPERATIONAL) -# elif 'ok' in line and 'T:' in line: -# self._baudrateDetectTestOk += 1 -# if self._baudrateDetectTestOk < 10: -# self._log("Baudrate test ok: %d" % (self._baudrateDetectTestOk)) -# self._sendCommand("M105") -#======= if self._grbl: self._sendCommand("$") else: @@ -1179,7 +1075,6 @@ class MachineCom(object): self._clear_to_send.set() except: self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, get_exception_string())) -#>>>>>>> upstream/maintenance else: self.close() self._errorValue = "No more baudrates to test, and no suitable baudrate found." @@ -1191,48 +1086,7 @@ class MachineCom(object): ### Connection attempt elif self._state == self.STATE_CONNECTING: -#<<<<<<< HEAD -# if self._grbl: -# # TODO get version string to detect connection -# self._sendCommand('$I'); -# if "Grbl" in line: -# self._changeState(self.STATE_LOCKED) -# else: -# if (line == "" or "wait" in line) and startSeen: -# self._sendCommand("M105") -# elif "start" in line: -# startSeen = True -# elif "ok" in line and startSeen: -# self._changeState(self.STATE_OPERATIONAL) -# if self._sdAvailable: -# self.refreshSdFiles() -# else: -# self.initSdCard() -# eventManager().fire(Events.CONNECTED, {"port": self._port, "baudrate": self._baudrate}) -# elif time.time() > self._timeout: -# self.close() -# -# ### Operational -# elif self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PAUSED or self._state == self.STATE_LOCKED: -# #Request the temperature on comm timeout (every 5 seconds) when we are not printing. -# if line == "" or "wait" in line: -# if self._resendDelta is not None: -# self._resendNextCommand() -# elif not self._commandQueue.empty(): -# self._sendCommand(self._commandQueue.get()) -# else: -# if self._grbl: -# self._sendCommand("?") -# else: -# self._sendCommand("M105") -# -# if self._grbl: -# tempRequestTimeout = getNewTimeout("position") -# else: -# tempRequestTimeout = getNewTimeout("detection") - ##print(tempRequestTimeout) - -#======= + if "start" in line and not startSeen: startSeen = True self._sendCommand("M110") @@ -1253,7 +1107,6 @@ class MachineCom(object): elif self._sendFromQueue(): pass -#>>>>>>> upstream/maintenance # resend -> start resend procedure from requested line elif line.lower().startswith("resend") or line.lower().startswith("rs"): self._handleResendRequest(line) @@ -1261,43 +1114,6 @@ class MachineCom(object): ### Printing elif self._state == self.STATE_PRINTING: if line == "" and time.time() > self._timeout: -#<<<<<<< HEAD -# if not self._grbl: -# self._log("Communication timeout during printing, forcing a line") -# line = 'ok' -# else: -# line = "" -# -# if self.isSdPrinting(): -# if time.time() > tempRequestTimeout and not heatingUp: -# if not self._grbl: -# self._sendCommand("M105") -# tempRequestTimeout = getNewTimeout("temperature") -# -# if time.time() > sdStatusRequestTimeout and not heatingUp: -# self._sendCommand("M27") -# sdStatusRequestTimeout = getNewTimeout("sdStatus") -# else: -# # Even when printing request the temperature every 5 seconds. -# if time.time() > tempRequestTimeout and not self.isStreaming(): -# if self._grbl: -# # disabled, caused race conditions during streaming resulting in a Invalid Gcode ID24 -# #self._commandQueue.put("?") -# #tempRequestTimeout = getNewTimeout("position") -# pass -# else: -# self._commandQueue.put("M105") -# tempRequestTimeout = getNewTimeout("temperature") -# -# if "ok" in line and swallowOk: -# swallowOk = False -# elif "ok" in line: -# if self._resendDelta is not None: -# self._resendNextCommand() -# elif not self._commandQueue.empty() and not self.isStreaming(): -# self._sendCommand(self._commandQueue.get(), True) -# else: -#======= if not self._long_running_command: self._log("Communication timeout during printing, forcing a line") self._sendCommand("M105") @@ -1318,7 +1134,6 @@ class MachineCom(object): if self._sendFromQueue(): pass elif not self.isSdPrinting(): -#>>>>>>> upstream/maintenance self._sendNext() elif line.lower().startswith("resend") or line.lower().startswith("rs"): @@ -1429,25 +1244,11 @@ class MachineCom(object): serial_obj = None try: -#<<<<<<< HEAD -# self._log("Connecting to: %s" % self._port) -# if self._baudrate == 0: -# self._serial = serial.Serial(str(self._port), 115200, timeout=settings().getFloat(["serial", "timeout", "connection"]), writeTimeout=10000, parity=serial.PARITY_ODD) -# else: -# self._serial = serial.Serial(str(self._port), self._baudrate, timeout=settings().getFloat(["serial", "timeout", "connection"]), writeTimeout=10000) -# self._serial = serial.Serial(str(self._port), self._baudrate, timeout=settings().getFloat(["serial", "timeout", "connection"]), writeTimeout=10000, parity=serial.PARITY_ODD) -# self._serial.close() -# self._serial.parity = serial.PARITY_NONE -# self._serial.open() -# if self._grbl : -# self._serial.setDTR(False) # Drop DTR to reset grbl. TODO init connection status by requesting version. -#======= self._log("Connecting to: %s" % (p)) programmer.connect(p) serial_obj = programmer.leaveISP() except ispBase.IspError as (e): self._log("Error while connecting to %s: %s" % (p, str(e))) -#>>>>>>> upstream/maintenance except: self._log("Unexpected error while connecting to serial port: %s %s" % (p, get_exception_string())) @@ -1559,44 +1360,6 @@ class MachineCom(object): return ret -#<<<<<<< HEAD -# def _sendNext(self): -# with self._sendNextLock: -# line = self._currentFile.getNext() -# if line is None: -# if self.isStreaming(): -# self._sendCommand("M29") -# -# remote = self._currentFile.getRemoteFilename() -# payload = { -# "local": self._currentFile.getLocalFilename(), -# "remote": remote, -# "time": self.getPrintTime() -# } -# -# self._currentFile = None -# self._changeState(self.STATE_OPERATIONAL) -# self._callback.mcFileTransferDone(remote) -# eventManager().fire(Events.TRANSFER_DONE, payload) -# self.refreshSdFiles() -# else: -# payload = { -# "file": self._currentFile.getFilename(), -# "filename": os.path.basename(self._currentFile.getFilename()), -# "origin": self._currentFile.getFileLocation(), -# "time": self.getPrintTime() -# } -# self._callback.mcPrintjobDone() -# self._changeState(self.STATE_OPERATIONAL) -# eventManager().fire(Events.PRINT_DONE, payload) -# -# # TODO fetch finish sequence from machine profiles -# self.sendCommand("M05"); -# self.sendCommand("G0X0Y0"); -# self.sendCommand("M09"); -# #self.sendCommand("M02"); -# return -#======= def _getNext(self): line = self._currentFile.getNext() if line is None: @@ -1609,7 +1372,6 @@ class MachineCom(object): "remote": remote, "time": self.getPrintTime() } -#>>>>>>> upstream/maintenance self._currentFile = None self._changeState(self.STATE_OPERATIONAL) @@ -1717,36 +1479,6 @@ class MachineCom(object): self._enqueue_for_sending(cmd, command_type=cmd_type) if not self.isStreaming(): -#<<<<<<< HEAD -# for hook in self._gcode_hooks: -# hook_cmd = self._gcode_hooks[hook](self, cmd) -# if hook_cmd and isinstance(hook_cmd, basestring): -# cmd = hook_cmd -# gcode = self._regex_command.search(cmd) -# if gcode: -# gcode = gcode.group(1) -# -# if gcode in gcodeToEvent: -# eventManager().fire(gcodeToEvent[gcode]) -# -# gcodeHandler = "_gcode_" + gcode -# if hasattr(self, gcodeHandler): -# cmd = getattr(self, gcodeHandler)(cmd) -# -# if cmd is not None: -# self._doSend(cmd, sendChecksum) -# -# def _doSend(self, cmd, sendChecksum=False): -# if sendChecksum or self._alwaysSendChecksum: -# lineNumber = self._currentLine -# self._addToLastLines(cmd) -# self._currentLine += 1 -# -# if self._grbl: -# self._doSendWithoutChecksum(cmd) # no checksums for grbl -# else: -# self._doSendWithChecksum(cmd, lineNumber) -#======= # trigger the "queued" phase only if we are not streaming to sd right now self._process_command_phase("queued", cmd, cmd_type, gcode=gcode) @@ -1908,7 +1640,6 @@ class MachineCom(object): elif hook_result_length == 2: # handler returned command and command_type command, command_type = handler_result -#>>>>>>> upstream/maintenance else: # handler returned a tuple of an unexpected length return original_tuple @@ -2041,10 +1772,6 @@ class MachineCom(object): elif s_idx != -1: # dwell time is specified in seconds _timeout = float(cmd[s_idx+1:]) -#<<<<<<< HEAD -# self._timeout = getNewTimeout("communication") + _timeout -# return cmd -#======= self._timeout = get_new_timeout("communication") + _timeout ##~~ command phase handlers @@ -2052,7 +1779,6 @@ class MachineCom(object): def _command_phase_sending(self, cmd, cmd_type=None, gcode=None): if gcode is not None and gcode in self._long_running_commands: self._long_running_command = True -#>>>>>>> upstream/maintenance ### MachineCom callback ################################################################################################ @@ -2220,14 +1946,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation): if self._handle is None: raise ValueError("File %s is not open for reading" % self._filename) -#<<<<<<< HEAD -# if self._lineCount is None: -# self._lineCount = 0 -# #return "M110 N0" -# return "" -# -#======= -#>>>>>>> upstream/maintenance try: offsets = self._offsets_callback() if self._offsets_callback is not None else None current_tool = self._current_tool_callback() if self._current_tool_callback is not None else None diff --git a/src/octoprint/util/comm_acc.py b/src/octoprint/util/comm_acc.py index 7683a195..b1864510 100644 --- a/src/octoprint/util/comm_acc.py +++ b/src/octoprint/util/comm_acc.py @@ -20,11 +20,11 @@ from collections import deque from octoprint.util.avr_isp import stk500v2 from octoprint.util.avr_isp import ispBase -from octoprint.settings import settings +from octoprint.settings import settings, default_settings from octoprint.events import eventManager, Events from octoprint.filemanager import valid_file_type from octoprint.filemanager.destinations import FileDestinations -#from octoprint.util import get_exception_string, getNewTimeout, sanitizeAscii, filterNonAscii +#from octoprint.util import get_exception_string, getNewTimeout, sanitize_ascii, filter_non_ascii from octoprint.util import get_exception_string, sanitize_ascii, filter_non_ascii, CountedEvent, RepeatedTimer from octoprint.util.virtual import VirtualPrinter @@ -118,8 +118,8 @@ class MachineCom(object): STATE_CLOSED_WITH_ERROR = 10 STATE_TRANSFERING_FILE = 11 STATE_LOCKED = 12 - - def __init__(self, port = None, baudrate = None, callbackObject = None): + + def __init__(self, port = None, baudrate = None, callbackObject = None, printerProfileManager = None): self._logger = logging.getLogger(__name__) self._serialLogger = logging.getLogger("SERIAL") @@ -131,9 +131,12 @@ class MachineCom(object): baudrate = 0 else: baudrate = settingsBaudrate + print('#####1', callbackObject) if callbackObject == None: callbackObject = MachineComPrintCallback() + print('#####2', callbackObject) + self._port = port self._baudrate = baudrate self._callback = callbackObject @@ -226,17 +229,17 @@ class MachineCom(object): if settings().get(["feature", "sdSupport"]): self._sdFileList = False self._sdFiles = [] - self._callback.mcSdFiles([]) + self._callback.on_comm_sd_files([]) self._log("entered state closed / closed with error. reseting character counter.") self.line_lengths = [] oldState = self.getStateString() self._state = newState self._log('Changing monitoring state from \'%s\' to \'%s\'' % (oldState, self.getStateString())) - self._callback.mcStateChange(newState) + self._callback.on_comm_state_change(newState) def _log(self, message): - self._callback.mcLog(message) + self._callback.on_comm_log(message) self._serialLogger.debug(message) def _addToLastLines(self, cmd): @@ -451,7 +454,7 @@ class MachineCom(object): self.sendCommand("M28 %s" % remoteFilename) eventManager().fire(Events.TRANSFER_STARTED, {"local": localFilename, "remote": remoteFilename}) - self._callback.mcFileTransferStarted(remoteFilename, self._currentFile.getFilesize()) + self._callback.on_comm_file_transfer_started(remoteFilename, self._currentFile.getFilesize()) def selectFile(self, filename, sd): if self.isBusy(): @@ -468,7 +471,7 @@ class MachineCom(object): "file": self._currentFile.getFilename(), "origin": self._currentFile.getFileLocation() }) - self._callback.mcFileSelected(filename, self._currentFile.getFilesize(), False) + self._callback.on_comm_file_selected(filename, self._currentFile.getFilesize(), False) def unselectFile(self): if self.isBusy(): @@ -476,7 +479,7 @@ class MachineCom(object): self._currentFile = None eventManager().fire(Events.FILE_DESELECTED) - self._callback.mcFileSelected(None, None, False) + self._callback.on_comm_file_selected(None, None, False) def cancelPrint(self): if not self.isOperational() or self.isStreaming(): @@ -568,7 +571,7 @@ class MachineCom(object): if settings().getBoolean(["feature", "sdAlwaysAvailable"]): self._sdAvailable = True self.refreshSdFiles() - self._callback.mcSdStateChange(self._sdAvailable) + self._callback.on_comm_sd_state_change(self._sdAvailable) def releaseSdCard(self): if not self.isOperational() or (self.isBusy() and self.isSdFileSelected()): @@ -579,8 +582,8 @@ class MachineCom(object): self._sdAvailable = False self._sdFiles = [] - self._callback.mcSdStateChange(self._sdAvailable) - self._callback.mcSdFiles(self._sdFiles) + self._callback.on_comm_sd_state_change(self._sdAvailable) + self._callback.on_comm_sd_files(self._sdFiles) ##~~ communication monitoring and handling @@ -657,8 +660,11 @@ class MachineCom(object): self._bedTemp = (actual, None) def _monitor(self): - feedbackControls = settings().getFeedbackControls() - pauseTriggers = settings().getPauseTriggers() + ### TODO hack + #feedbackControls = settings().getFeedbackControls() + feedbackControls = None + #pauseTriggers = settings().getPauseTriggers() + pauseTriggers = None feedbackErrors = [] #Open the serial port. @@ -673,10 +679,10 @@ class MachineCom(object): self._changeState(self.STATE_CONNECTING) #Start monitoring the serial port. - self._timeout = getNewTimeout("communication") + self._timeout = get_new_timeout("communication") - tempRequestTimeout = getNewTimeout("temperature") - sdStatusRequestTimeout = getNewTimeout("sdStatus") + tempRequestTimeout = get_new_timeout("temperature") + sdStatusRequestTimeout = get_new_timeout("sdStatus") startSeen = not settings().getBoolean(["feature", "waitForStartOnConnect"]) heatingUp = False @@ -691,7 +697,7 @@ class MachineCom(object): if line is None: break if line.strip() is not "": - self._timeout = getNewTimeout("communication") + self._timeout = get_new_timeout("communication") ##~~ debugging output handling if line.startswith("//"): @@ -707,7 +713,7 @@ class MachineCom(object): self.setPause(False) elif action_command == "disconnect": self._log("Disconnecting on request of the printer...") - self._callback.mcForceDisconnect() + self._callback.on_comm_force_disconnect() else: for hook in self._printer_action_hooks: self._printer_action_hooks[hook](self, line, action_command) @@ -737,7 +743,7 @@ class MachineCom(object): size = None if valid_file_type(filename, "gcode"): - if filterNonAscii(filename): + if filter_non_ascii(filename): self._logger.warn("Got a file from printer's SD that has a non-ascii filename (%s), that shouldn't happen according to the protocol" % filename) else: self._sdFiles.append((filename, size)) @@ -746,7 +752,7 @@ class MachineCom(object): ##~~ Temperature processing if ' T:' in line or line.startswith('T:') or ' T0:' in line or line.startswith('T0:'): self._processTemperatures(line) - self._callback.mcTempUpdate(self._temp, self._bedTemp) + self._callback.on_comm_temperature_update(self._temp, self._bedTemp) #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 'ok' in line and self._heatupWaitStartTime: @@ -765,7 +771,7 @@ class MachineCom(object): self._temp[toolNum] = (actual, target) else: self._temp[toolNum] = (None, target) - self._callback.mcTempUpdate(self._temp, self._bedTemp) + self._callback.on_comm_temperature_update(self._temp, self._bedTemp) except ValueError: pass elif matchBed is not None: @@ -776,12 +782,13 @@ class MachineCom(object): self._bedTemp = (actual, target) else: self._bedTemp = (None, target) - self._callback.mcTempUpdate(self._temp, self._bedTemp) + self._callback.on_comm_temperature_update(self._temp, self._bedTemp) except ValueError: pass # GRBL Position update if self._grbl : + print ('state: ', self.getStateString(), line) if 'MPos:' in line: if grblLastStatus == line: @@ -791,7 +798,7 @@ class MachineCom(object): grblLastStatus = line - if("Alarm" in line): + if("Alarm lock" in line): self._changeState(self.STATE_LOCKED) if("Idle" in line and self._state == self.STATE_LOCKED): self._changeState(self.STATE_OPERATIONAL) @@ -810,7 +817,7 @@ class MachineCom(object): pos = parts[2].split(",") WPos = (float(pos[0]), float(pos[1]), float( pos[2].strip(">") )) - self._callback.mcPosUpdate(MPos, WPos) + self._callback.on_comm_pos_update(MPos, WPos) if("ALARM: Hard/soft limit" in line): errorMsg = "Machine Limit Hit. Please reset the machine and do a homing cycle" @@ -838,7 +845,7 @@ class MachineCom(object): elif 'SD init fail' in line or 'volume.init failed' in line or 'openRoot failed' in line: self._sdAvailable = False self._sdFiles = [] - self._callback.mcSdStateChange(self._sdAvailable) + self._callback.on_comm_sd_state_change(self._sdAvailable) elif 'Not SD printing' in line: if self.isSdFileSelected() and self.isPrinting(): # something went wrong, printer is reporting that we actually are not printing right now... @@ -847,18 +854,18 @@ class MachineCom(object): elif 'SD card ok' in line and not self._sdAvailable: self._sdAvailable = True self.refreshSdFiles() - self._callback.mcSdStateChange(self._sdAvailable) + self._callback.on_comm_sd_state_change(self._sdAvailable) elif 'Begin file list' in line: self._sdFiles = [] self._sdFileList = True elif 'End file list' in line: self._sdFileList = False - self._callback.mcSdFiles(self._sdFiles) + self._callback.on_comm_sd_files(self._sdFiles) elif 'SD printing byte' in line: # answer to M27, at least on Marlin, Repetier and Sprinter: "SD printing byte %d/%d" match = self._regex_sdPrintingByte.search(line) self._currentFile.setFilepos(int(match.group(1))) - self._callback.mcProgress() + self._callback.on_comm_progress() elif 'File opened' in line: # answer to M23, at least on Marlin, Repetier and Sprinter: "File opened:%s Size:%d" match = self._regex_sdFileOpened.search(line) @@ -866,7 +873,7 @@ class MachineCom(object): elif 'File selected' in line: # final answer to M23, at least on Marlin, Repetier and Sprinter: "File selected" if self._currentFile is not None: - self._callback.mcFileSelected(self._currentFile.getFilename(), self._currentFile.getFilesize(), True) + self._callback.on_comm_file_selected(self._currentFile.getFilename(), self._currentFile.getFilesize(), True) eventManager().fire(Events.FILE_SELECTED, { "file": self._currentFile.getFilename(), "origin": self._currentFile.getFileLocation() @@ -879,7 +886,7 @@ class MachineCom(object): elif 'Done printing file' in line: # printer is reporting file finished printing self._sdFilePos = 0 - self._callback.mcPrintjobDone() + self._callback.on_comm_print_job_done() self._changeState(self.STATE_OPERATIONAL) eventManager().fire(Events.PRINT_DONE, { "file": self._currentFile.getFilename(), @@ -897,7 +904,7 @@ class MachineCom(object): and line != 'echo:Unknown command:""\n' \ and line != "Unsupported statement" \ and self.isOperational(): - self._callback.mcMessage(line) + self._callback.on_comm_message(line) ##~~ Parsing for feedback commands if feedbackControls: @@ -915,7 +922,7 @@ class MachineCom(object): formatFunction = unicode.format if formatFunction is not None: - self._callback.mcReceivedRegisteredMessage(name, formatFunction(template, *(match.groups("n/a")))) + self._callback.on_comm_ReceivedRegisteredMessage(name, formatFunction(template, *(match.groups("n/a")))) except: if not name in feedbackErrors: self._logger.info("Something went wrong with feedbackControl \"%s\": " % name, exc_info=True) @@ -960,7 +967,7 @@ class MachineCom(object): self._log("Trying baudrate: %d" % (baudrate)) self._baudrateDetectRetry = 5 self._baudrateDetectTestOk = 0 - self._timeout = getNewTimeout("communication") + self._timeout = get_new_timeout("communication") self._serial.write('\n') # self._sendCommand("M105") if self._grbl: @@ -1028,9 +1035,9 @@ class MachineCom(object): self._sendCommand("M105") if self._grbl: - tempRequestTimeout = getNewTimeout("position") + tempRequestTimeout = get_new_timeout("position") else: - tempRequestTimeout = getNewTimeout("detection") + tempRequestTimeout = get_new_timeout("detection") ###print(tempRequestTimeout) # resend -> start resend procedure from requested line @@ -1052,22 +1059,22 @@ class MachineCom(object): if time.time() > tempRequestTimeout and not heatingUp: if not self._grbl: self._sendCommand("M105") - tempRequestTimeout = getNewTimeout("temperature") + tempRequestTimeout = get_new_timeout("temperature") if time.time() > sdStatusRequestTimeout and not heatingUp: self._sendCommand("M27") - sdStatusRequestTimeout = getNewTimeout("sdStatus") + sdStatusRequestTimeout = get_new_timeout("sdStatus") else: # Even when printing request the temperature every 5 seconds. if time.time() > tempRequestTimeout and not self.isStreaming(): if self._grbl: # disabled, caused race conditions during streaming resulting in a Invalid Gcode ID24 self._commandQueue.put("?") - tempRequestTimeout = getNewTimeout("position") + tempRequestTimeout = get_new_timeout("position") #pass else: self._commandQueue.put("M105") - tempRequestTimeout = getNewTimeout("temperature") + tempRequestTimeout = get_new_timeout("temperature") if "ok" in line and swallowOk: swallowOk = False @@ -1094,6 +1101,7 @@ class MachineCom(object): self._log("Connection closed, closing down monitor") def _openSerial(self): + print('_openSerial') if self._port == 'AUTO': self._changeState(self.STATE_DETECT_SERIAL) programmer = stk500v2.Stk500v2() @@ -1181,7 +1189,7 @@ class MachineCom(object): if ret == '': #self._log("Recv: TIMEOUT") return '' - self._log("Recv: %s" % sanitizeAscii(ret)) + self._log("Recv: %s" % sanitize_ascii(ret)) return ret def _sendNext(self): @@ -1200,7 +1208,7 @@ class MachineCom(object): self._currentFile = None self._changeState(self.STATE_OPERATIONAL) - self._callback.mcFileTransferDone(remote) + self._callback.on_comm_file_transfer_done(remote) eventManager().fire(Events.TRANSFER_DONE, payload) self.refreshSdFiles() else: @@ -1210,7 +1218,7 @@ class MachineCom(object): "origin": self._currentFile.getFileLocation(), "time": self.getPrintTime() } - self._callback.mcPrintjobDone() + self._callback.on_comm_print_job_done() self._changeState(self.STATE_OPERATIONAL) eventManager().fire(Events.PRINT_DONE, payload) @@ -1222,7 +1230,7 @@ class MachineCom(object): return self._sendCommand(line, True) - self._callback.mcProgress() + self._callback.on_comm_progress() def _handleResendRequest(self, line): lineToResend = None @@ -1344,7 +1352,7 @@ class MachineCom(object): z = float(match.group(1)) if self._currentZ != z: self._currentZ = z - self._callback.mcZChange(z) + self._callback.on_comm_z_change(z) except ValueError: pass return cmd @@ -1432,51 +1440,51 @@ class MachineCom(object): elif s_idx != -1: # dwell time is specified in seconds _timeout = float(cmd[s_idx+1:]) - self._timeout = getNewTimeout("communication") + _timeout + self._timeout = get_new_timeout("communication") + _timeout return cmd ### MachineCom callback ################################################################################################ class MachineComPrintCallback(object): - def mcLog(self, message): + def on_comm_log(self, message): pass - def mcTempUpdate(self, temp, bedTemp): + def on_comm_temperature_update(self, temp, bedTemp): pass - def mcStateChange(self, state): + def on_comm_state_change(self, state): pass - def mcMessage(self, message): + def on_comm_message(self, message): pass - def mcProgress(self): + def on_comm_progress(self): pass - def mcZChange(self, newZ): + def on_comm_print_job_done(self): pass - def mcFileSelected(self, filename, filesize, sd): + def on_comm_z_change(self, newZ): pass - def mcSdStateChange(self, sdReady): + def on_comm_file_selected(self, filename, filesize, sd): pass - def mcSdFiles(self, files): + def on_comm_sd_state_change(self, sdReady): pass - def mcSdPrintingDone(self): + def on_comm_sd_files(self, files): pass - def mcFileTransferStarted(self, filename, filesize): + def on_comm_file_transfer_started(self, filename, filesize): pass - def mcReceivedRegisteredMessage(self, command, message): + def on_comm_file_transfer_done(self, filename): pass - def mcForceDisconnect(self): + def on_comm_force_disconnect(self): pass - + ### Printing file information classes ################################################################################## class PrintingFileInformation(object): @@ -1679,3 +1687,15 @@ class StreamingGcodeFileInformation(PrintingGcodeFileInformation): def getRemoteFilename(self): return self._remoteFilename + + +def get_new_timeout(type): + now = time.time() + return now + get_interval(type) + + +def get_interval(type): + if type not in default_settings["serial"]["timeout"]: + return 0 + else: + return settings().getFloat(["serial", "timeout", type]) \ No newline at end of file