This commit is contained in:
Teja 2015-07-03 17:08:15 +02:00
parent 90b20d0be6
commit fa1bad7b7c
13 changed files with 685 additions and 922 deletions

View file

@ -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),

View file

@ -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)

View file

@ -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):

View file

@ -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"

View file

@ -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

View file

@ -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"
]);
});

View file

@ -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"]);
};

View file

@ -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()) {

View file

@ -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,

View file

@ -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([

View file

@ -19,13 +19,15 @@
<img alt="Mr Beam Logo" src="{{ url_for('static', filename='img/mr-typo-red_x120.png') }}">
</a>
</div>
<!-- Navbar -->
<ul class="nav nav-pills">
<li class="active"><a href="#workingarea" data-toggle="tab" id="wa_tab_btn">working area</a></li>
<li><a href="#designlib" data-toggle="tab">design library</a></li>
<li><a href="#focus" data-toggle="tab">focus</a></li>
<li><a href="#term" data-toggle="tab">terminal</a></li>
{% for data in navbarEntries %}
{% for key in templates.navbar.order %}
{% set data = templates.navbar.entries[key] %}
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %}
<li id="{{ data._div }}"
{% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %}
@ -36,6 +38,7 @@
</li>
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
{% endfor %}
</ul>
</div>
</nav>
@ -116,7 +119,7 @@
</div>
</div>
<div class="accordion-body collapse in" id="connection" data-bind="visible: (isErrorOrClosed() || isConnecting()) && loginState.isUser()">
<div class="accordion-body collapse in" id="connection_wrapper" data-bind="visible: (isErrorOrClosed()) && loginState.isUser()">
<div class="accordion-inner">
<label for="connection_ports" data-bind="css: {disabled: !isErrorOrClosed()}, enable: isErrorOrClosed() && loginState.isUser()">{{ _('Serial Port') }}</label>
<select id="connection_ports" data-bind="options: portOptions, optionsCaption: 'AUTO', value: selectedPort, css: {disabled: !isErrorOrClosed()}, enable: isErrorOrClosed() && loginState.isUser()"></select>
@ -131,7 +134,8 @@
<button class="btn btn-block" id="printer_connect" data-bind="click: connect, text: buttonText(), enable: loginState.isUser()">{{ _('Connect') }}</button>
</div>
</div>
<div class="accordion-body collapse in" id="state" data-bind="visible: !isErrorOrClosed() && loginState.isUser()">
<div class="accordion-body collapse in" id="state_wrapper" data-bind="visible: !isErrorOrClosed() && loginState.isUser()">
<div class="accordion-inner">
{{ _('Machine State') }}: <strong data-bind="text: stateString"></strong><br>
@ -460,9 +464,9 @@
</div>
<div class="span8">
<div class="designlib" >
<div class="" >
<div id="files" >
<div id="files">
<div id="files_wrapper">
<div class="accordion-inner">
<div class="gcode_files" data-bind="slimScrolledForeach: listHelper.paginatedItems" >
@ -617,20 +621,21 @@
<!-- Plugin template files -->
{% if templatePlugins %}
{% for plugin_name in templatePlugins %}
{% include plugin_name+".jinja2" ignore missing %}
{% endfor %}
{% endif %}
<!-- End plugin template files -->
<!-- Plugin template files -->
{% if templatePlugins %}
{% for plugin_name in templatePlugins %}
{% include plugin_name+".jinja2" ignore missing %}
{% endfor %}
{% endif %}
<!-- End plugin template files -->
<!-- Dialogs -->
<!-- Dialogs -->
{% include 'dialogs/confirmation.jinja2' %}
{% include 'dialogs/firstrun.jinja2' %}
{#% include 'dialogs/settings.jinja2' %#}
{% include 'dialogs/slicing.jinja2' %}
{% include 'dialogs/usersettings.jinja2' %}
<!-- End of dialogs -->
<!-- Overlays -->

View file

@ -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<grbl>.+)\.(?P<git>[0-9a-f]{7})(?P<dirty>-dirty)?:(?P<minor>.*)\]", 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

View file

@ -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])