Switched Timelapses to using Eventbus instead of direct connection
parent
ed9e93f379
commit
236e26979f
|
@ -40,8 +40,9 @@ Available Events:
|
||||||
* ''PowerOn'': the GCode has turned on the printer power via M80
|
* ''PowerOn'': the GCode has turned on the printer power via M80
|
||||||
* ''PowerOff'': the GCode has turned on the printer power via M81
|
* ''PowerOff'': the GCode has turned on the printer power via M81
|
||||||
* ''Upload'': a gcode file upload has been uploaded (data is filename)
|
* ''Upload'': a gcode file upload has been uploaded (data is filename)
|
||||||
* ''LoadStart'': a gcode file load has started (data is filename)
|
* ''FileSelected'': a gcode file has been selected for printing (data is filename)
|
||||||
* ''LoadDone'': a gcode file load has finished (data is filename)
|
* ''TransferStart'': a gcode file transfer to SD has started (data is filename)
|
||||||
|
* ''TransferDone'': a gcode file transfer to SD has finished (data is filename)
|
||||||
* ''PrintStarted'': a print has started
|
* ''PrintStarted'': a print has started
|
||||||
* ''PrintFailed'': a print failed
|
* ''PrintFailed'': a print failed
|
||||||
* ''PrintDone'': a print completed successfully
|
* ''PrintDone'': a print completed successfully
|
||||||
|
|
|
@ -41,7 +41,7 @@ class EventManager(object):
|
||||||
|
|
||||||
if not event in self._registeredListeners.keys():
|
if not event in self._registeredListeners.keys():
|
||||||
return
|
return
|
||||||
self._logger.debug("Firing event: %s (%r)" % (event, payload))
|
self._logger.debug("Firing event: %s (Payload: %r)" % (event, payload))
|
||||||
|
|
||||||
eventListeners = self._registeredListeners[event]
|
eventListeners = self._registeredListeners[event]
|
||||||
for listener in eventListeners:
|
for listener in eventListeners:
|
||||||
|
@ -107,6 +107,20 @@ class GenericEventListener(object):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class DebugEventListener(GenericEventListener):
|
||||||
|
def __init__(self):
|
||||||
|
GenericEventListener.__init__(self)
|
||||||
|
|
||||||
|
events = ["Startup", "Connected", "Disconnected", "ClientOpen", "ClientClosed", "PowerOn", "PowerOff", "Upload",
|
||||||
|
"FileSelected", "TransferStarted", "TransferDone", "PrintStarted", "PrintDone", "PrintFailed",
|
||||||
|
"Cancelled", "Home", "ZChange", "Paused", "Waiting", "Cooling", "Alert", "Conveyor", "Eject",
|
||||||
|
"CaptureStart", "CaptureDone", "MovieDone", "EStop", "Error"]
|
||||||
|
self.subscribe(events)
|
||||||
|
|
||||||
|
def eventCallback(self, event, payload):
|
||||||
|
GenericEventListener.eventCallback(self, event, payload)
|
||||||
|
self._logger.debug("Received event: %s (Payload: %r)" % (event, payload))
|
||||||
|
|
||||||
class CommandTrigger(GenericEventListener):
|
class CommandTrigger(GenericEventListener):
|
||||||
def __init__(self, triggerType, printer):
|
def __init__(self, triggerType, printer):
|
||||||
GenericEventListener.__init__(self)
|
GenericEventListener.__init__(self)
|
||||||
|
@ -194,9 +208,8 @@ class CommandTrigger(GenericEventListener):
|
||||||
if "job" in currentData.keys() and currentData["job"] is not None:
|
if "job" in currentData.keys() and currentData["job"] is not None:
|
||||||
params["filename"] = currentData["job"]["filename"]
|
params["filename"] = currentData["job"]["filename"]
|
||||||
if "progress" in currentData.keys() and currentData["progress"] is not None \
|
if "progress" in currentData.keys() and currentData["progress"] is not None \
|
||||||
and "progress" in currentData["progress"].keys() and currentData["progress"]["progress"] is not None \
|
and "progress" in currentData["progress"].keys() and currentData["progress"]["progress"] is not None:
|
||||||
and currentData["job"]["lines"] is not None:
|
params["progress"] = str(round(currentData["progress"]["progress"] * 100))
|
||||||
params["progress"] = str(round(currentData["progress"]["progress"] * 100 / currentData["job"]["lines"]))
|
|
||||||
|
|
||||||
return command % params
|
return command % params
|
||||||
|
|
||||||
|
|
|
@ -217,7 +217,7 @@ class Printer():
|
||||||
|
|
||||||
def setTimelapse(self, timelapse):
|
def setTimelapse(self, timelapse):
|
||||||
if self._timelapse is not None and self.isPrinting():
|
if self._timelapse is not None and self.isPrinting():
|
||||||
self._timelapse.onPrintjobStopped()
|
self._timelapse.stopTimelapse()
|
||||||
del self._timelapse
|
del self._timelapse
|
||||||
self._timelapse = timelapse
|
self._timelapse = timelapse
|
||||||
|
|
||||||
|
@ -368,13 +368,6 @@ class Printer():
|
||||||
"""
|
"""
|
||||||
oldState = self._state
|
oldState = self._state
|
||||||
|
|
||||||
# forward relevant state changes to timelapse
|
|
||||||
if self._timelapse is not None:
|
|
||||||
if oldState == self._comm.STATE_PRINTING and state != self._comm.STATE_PAUSED:
|
|
||||||
self._timelapse.onPrintjobStopped()
|
|
||||||
elif state == self._comm.STATE_PRINTING and oldState != self._comm.STATE_PAUSED:
|
|
||||||
self._timelapse.onPrintjobStarted(self._selectedFile["filename"])
|
|
||||||
|
|
||||||
# forward relevant state changes to gcode manager
|
# forward relevant state changes to gcode manager
|
||||||
if self._comm is not None and oldState == self._comm.STATE_PRINTING:
|
if self._comm is not None and oldState == self._comm.STATE_PRINTING:
|
||||||
if self._selectedFile is not None:
|
if self._selectedFile is not None:
|
||||||
|
@ -409,11 +402,9 @@ class Printer():
|
||||||
"""
|
"""
|
||||||
oldZ = self._currentZ
|
oldZ = self._currentZ
|
||||||
# only do this if we hit a new Z peak level. Some slicers do a Z-lift when retracting / moving without printing
|
# only do this if we hit a new Z peak level. Some slicers do a Z-lift when retracting / moving without printing
|
||||||
# and some do ananti-backlash up-then-down movement when advancing layers
|
# and some do anti-backlash up-then-down movement when advancing layers
|
||||||
if newZ > self.peakZ:
|
if newZ > self.peakZ:
|
||||||
self.peakZ = newZ
|
self.peakZ = newZ
|
||||||
if self._timelapse is not None:
|
|
||||||
self._timelapse.onZChange(oldZ, newZ)
|
|
||||||
eventManager().fire("ZChange", newZ)
|
eventManager().fire("ZChange", newZ)
|
||||||
|
|
||||||
self._setCurrentZ(newZ)
|
self._setCurrentZ(newZ)
|
||||||
|
|
|
@ -64,6 +64,7 @@ class PrinterStateConnection(tornadio2.SocketConnection):
|
||||||
gcodeManager.registerCallback(self)
|
gcodeManager.registerCallback(self)
|
||||||
|
|
||||||
self._eventManager.fire("ClientOpened")
|
self._eventManager.fire("ClientOpened")
|
||||||
|
self._eventManager.subscribe("MovieDone", self._onMovieDone)
|
||||||
|
|
||||||
def on_close(self):
|
def on_close(self):
|
||||||
self._logger.info("Closed client connection")
|
self._logger.info("Closed client connection")
|
||||||
|
@ -72,6 +73,7 @@ class PrinterStateConnection(tornadio2.SocketConnection):
|
||||||
gcodeManager.unregisterCallback(self)
|
gcodeManager.unregisterCallback(self)
|
||||||
|
|
||||||
self._eventManager.fire("ClientClosed")
|
self._eventManager.fire("ClientClosed")
|
||||||
|
self._eventManager.unsubscribe("MovieDone", self._onMovieDone)
|
||||||
|
|
||||||
def on_message(self, message):
|
def on_message(self, message):
|
||||||
pass
|
pass
|
||||||
|
@ -115,6 +117,9 @@ class PrinterStateConnection(tornadio2.SocketConnection):
|
||||||
with self._temperatureBacklogMutex:
|
with self._temperatureBacklogMutex:
|
||||||
self._temperatureBacklog.append(data)
|
self._temperatureBacklog.append(data)
|
||||||
|
|
||||||
|
def _onMovieDone(self, event, payload):
|
||||||
|
self.sendUpdateTrigger("timelapseFiles")
|
||||||
|
|
||||||
# Did attempt to make webserver an encapsulated class but ended up with __call__ failures
|
# Did attempt to make webserver an encapsulated class but ended up with __call__ failures
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
|
@ -364,9 +369,9 @@ def getTimelapseData():
|
||||||
file["url"] = url_for("downloadTimelapse", filename=file["name"])
|
file["url"] = url_for("downloadTimelapse", filename=file["name"])
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"type": type,
|
"type": type,
|
||||||
"config": additionalConfig,
|
"config": additionalConfig,
|
||||||
"files": files
|
"files": files
|
||||||
})
|
})
|
||||||
|
|
||||||
@app.route(BASEURL + "timelapse/<filename>", methods=["GET"])
|
@app.route(BASEURL + "timelapse/<filename>", methods=["GET"])
|
||||||
|
@ -719,6 +724,8 @@ class Server():
|
||||||
# setup system and gcode command triggers
|
# setup system and gcode command triggers
|
||||||
events.SystemCommandTrigger(printer)
|
events.SystemCommandTrigger(printer)
|
||||||
events.GcodeCommandTrigger(printer)
|
events.GcodeCommandTrigger(printer)
|
||||||
|
if self._debug:
|
||||||
|
events.DebugEventListener()
|
||||||
|
|
||||||
if settings().getBoolean(["accessControl", "enabled"]):
|
if settings().getBoolean(["accessControl", "enabled"]):
|
||||||
userManagerName = settings().get(["accessControl", "userManager"])
|
userManagerName = settings().get(["accessControl", "userManager"])
|
||||||
|
|
|
@ -999,8 +999,7 @@ function TimelapseViewModel(loginStateViewModel) {
|
||||||
self.isLoading(data.flags.loading);
|
self.isLoading(data.flags.loading);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.removeFile = function() {
|
self.removeFile = function(filename) {
|
||||||
var filename = this.name;
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: AJAX_BASEURL + "timelapse/" + filename,
|
url: AJAX_BASEURL + "timelapse/" + filename,
|
||||||
type: "DELETE",
|
type: "DELETE",
|
||||||
|
@ -1526,6 +1525,8 @@ function DataUpdater(loginStateViewModel, connectionViewModel, printerStateViewM
|
||||||
self._socket.on("updateTrigger", function(type) {
|
self._socket.on("updateTrigger", function(type) {
|
||||||
if (type == "gcodeFiles") {
|
if (type == "gcodeFiles") {
|
||||||
gcodeFilesViewModel.requestData();
|
gcodeFilesViewModel.requestData();
|
||||||
|
} else if (type == "timelapseFiles") {
|
||||||
|
timelapseViewModel.requestData();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1737,28 +1738,28 @@ function ItemListHelper(listType, supportedSorting, supportedFilters, defaultSor
|
||||||
|
|
||||||
self._saveCurrentSortingToLocalStorage = function() {
|
self._saveCurrentSortingToLocalStorage = function() {
|
||||||
if ( self._initializeLocalStorage() ) {
|
if ( self._initializeLocalStorage() ) {
|
||||||
var currentSorting = self.currentSorting();
|
var currentSorting = self.currentSorting();
|
||||||
if (currentSorting !== undefined)
|
if (currentSorting !== undefined)
|
||||||
localStorage[self.listType + "." + "currentSorting"] = currentSorting;
|
localStorage[self.listType + "." + "currentSorting"] = currentSorting;
|
||||||
else
|
else
|
||||||
localStorage[self.listType + "." + "currentSorting"] = undefined;
|
localStorage[self.listType + "." + "currentSorting"] = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._loadCurrentSortingFromLocalStorage = function() {
|
self._loadCurrentSortingFromLocalStorage = function() {
|
||||||
if ( self._initializeLocalStorage() ) {
|
if ( self._initializeLocalStorage() ) {
|
||||||
if (_.contains(_.keys(supportedSorting), localStorage[self.listType + "." + "currentSorting"]))
|
if (_.contains(_.keys(supportedSorting), localStorage[self.listType + "." + "currentSorting"]))
|
||||||
self.currentSorting(localStorage[self.listType + "." + "currentSorting"]);
|
self.currentSorting(localStorage[self.listType + "." + "currentSorting"]);
|
||||||
else
|
else
|
||||||
self.currentSorting(defaultSorting);
|
self.currentSorting(defaultSorting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._saveCurrentFiltersToLocalStorage = function() {
|
self._saveCurrentFiltersToLocalStorage = function() {
|
||||||
if ( self._initializeLocalStorage() ) {
|
if ( self._initializeLocalStorage() ) {
|
||||||
var filters = _.intersection(_.keys(self.supportedFilters), self.currentFilters());
|
var filters = _.intersection(_.keys(self.supportedFilters), self.currentFilters());
|
||||||
localStorage[self.listType + "." + "currentFilters"] = JSON.stringify(filters);
|
localStorage[self.listType + "." + "currentFilters"] = JSON.stringify(filters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._loadCurrentFiltersFromLocalStorage = function() {
|
self._loadCurrentFiltersFromLocalStorage = function() {
|
||||||
|
|
|
@ -542,7 +542,7 @@
|
||||||
<tr data-bind="attr: {title: name}">
|
<tr data-bind="attr: {title: name}">
|
||||||
<td class="timelapse_files_name" data-bind="text: name"></td>
|
<td class="timelapse_files_name" data-bind="text: name"></td>
|
||||||
<td class="timelapse_files_size" data-bind="text: size"></td>
|
<td class="timelapse_files_size" data-bind="text: size"></td>
|
||||||
<td class="timelapse_files_action"><a href="#" class="icon-trash" data-bind="click: function() { if ($root.loginState.isUser()) { $parent.removeFile(); } else { return; } }, css: {disabled: !$root.loginState.isUser()}"></a> | <a href="#" class="icon-download" data-bind="attr: {href: url}"></a></td>
|
<td class="timelapse_files_action"><a href="#" class="icon-trash" data-bind="click: function() { if ($root.loginState.isUser()) { $parent.removeFile($data.name); } else { return; } }, css: {disabled: !$root.loginState.isUser()}"></a> | <a href="#" class="icon-download" data-bind="attr: {href: url}"></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -47,13 +47,30 @@ class Timelapse(object):
|
||||||
self._renderThread = None
|
self._renderThread = None
|
||||||
self._captureMutex = threading.Lock()
|
self._captureMutex = threading.Lock()
|
||||||
|
|
||||||
def onPrintjobStarted(self, gcodeFile):
|
eventManager().subscribe("PrintStarted", self.onPrintStarted)
|
||||||
self.startTimelapse(gcodeFile)
|
eventManager().subscribe("PrintFailed", self.onPrintDone)
|
||||||
|
eventManager().subscribe("PrintDone", self.onPrintDone)
|
||||||
|
self.subscribeToEvents()
|
||||||
|
|
||||||
def onPrintjobStopped(self):
|
def onPrintStarted(self, event, payload):
|
||||||
|
"""
|
||||||
|
Override this to perform additional actions upon start of a print job.
|
||||||
|
"""
|
||||||
|
self.startTimelapse(payload)
|
||||||
|
|
||||||
|
def onPrintDone(self, event, payload):
|
||||||
|
"""
|
||||||
|
Override this to perform additional actions upon the stop of a print job.
|
||||||
|
"""
|
||||||
self.stopTimelapse()
|
self.stopTimelapse()
|
||||||
|
|
||||||
def onZChange(self, oldZ, newZ):
|
def subscribeToEvents(self):
|
||||||
|
"""
|
||||||
|
Override this method to subscribe to additional events. Events that are already subscribed:
|
||||||
|
* PrintStarted - self.onPrintStarted
|
||||||
|
* PrintFailed - self.onPrintDone
|
||||||
|
* PrintDone - self.onPrintDone
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def startTimelapse(self, gcodeFile):
|
def startTimelapse(self, gcodeFile):
|
||||||
|
@ -96,7 +113,7 @@ class Timelapse(object):
|
||||||
ffmpeg = settings().get(["webcam", "ffmpeg"])
|
ffmpeg = settings().get(["webcam", "ffmpeg"])
|
||||||
bitrate = settings().get(["webcam", "bitrate"])
|
bitrate = settings().get(["webcam", "bitrate"])
|
||||||
if ffmpeg is None or bitrate is None:
|
if ffmpeg is None or bitrate is None:
|
||||||
self._logger.warn("Cannot create movie, path to ffmpeg is unset")
|
self._logger.warn("Cannot create movie, path to ffmpeg or desired bitrate is unset")
|
||||||
return
|
return
|
||||||
|
|
||||||
input = os.path.join(self._captureDir, "tmp_%05d.jpg")
|
input = os.path.join(self._captureDir, "tmp_%05d.jpg")
|
||||||
|
@ -119,8 +136,11 @@ class Timelapse(object):
|
||||||
# finalize command with output file
|
# finalize command with output file
|
||||||
self._logger.debug("Rendering movie to %s" % output)
|
self._logger.debug("Rendering movie to %s" % output)
|
||||||
command.append(output)
|
command.append(output)
|
||||||
subprocess.call(command)
|
try:
|
||||||
eventManager().fire("MovieDone", output);
|
subprocess.check_call(command)
|
||||||
|
eventManager().fire("MovieDone", output);
|
||||||
|
except subprocess.CalledProcessError as (e):
|
||||||
|
self._logger.warn("Could not render movie, got return code %r" % e.returncode)
|
||||||
|
|
||||||
def cleanCaptureDir(self):
|
def cleanCaptureDir(self):
|
||||||
if not os.path.isdir(self._captureDir):
|
if not os.path.isdir(self._captureDir):
|
||||||
|
@ -137,35 +157,38 @@ class ZTimelapse(Timelapse):
|
||||||
Timelapse.__init__(self)
|
Timelapse.__init__(self)
|
||||||
self._logger.debug("ZTimelapse initialized")
|
self._logger.debug("ZTimelapse initialized")
|
||||||
|
|
||||||
def onZChange(self, oldZ, newZ):
|
def subscribeToEvents(self):
|
||||||
self._logger.debug("Z change detected, capturing image")
|
eventManager().subscribe("ZChange", self._onZChange)
|
||||||
|
|
||||||
|
def _onZChange(self, event, payload):
|
||||||
self.captureImage()
|
self.captureImage()
|
||||||
|
|
||||||
class TimedTimelapse(Timelapse):
|
class TimedTimelapse(Timelapse):
|
||||||
def __init__(self, interval=1):
|
def __init__(self, interval=1):
|
||||||
Timelapse.__init__(self)
|
Timelapse.__init__(self)
|
||||||
|
|
||||||
self._interval = interval
|
self._interval = interval
|
||||||
if self._interval < 1:
|
if self._interval < 1:
|
||||||
self._interval = 1 # force minimum interval of 1s
|
self._interval = 1 # force minimum interval of 1s
|
||||||
|
|
||||||
self._timerThread = None
|
self._timerThread = None
|
||||||
|
|
||||||
self._logger.debug("TimedTimelapse initialized")
|
self._logger.debug("TimedTimelapse initialized")
|
||||||
|
|
||||||
def interval(self):
|
def interval(self):
|
||||||
return self._interval
|
return self._interval
|
||||||
|
|
||||||
def onPrintjobStarted(self, filename):
|
def onPrintStarted(self, event, payload):
|
||||||
Timelapse.onPrintjobStarted(self, filename)
|
Timelapse.onPrintStarted(self, event, payload)
|
||||||
if self._timerThread is not None:
|
if self._timerThread is not None:
|
||||||
return
|
return
|
||||||
|
|
||||||
self._timerThread = threading.Thread(target=self.timerWorker)
|
self._timerThread = threading.Thread(target=self._timerWorker)
|
||||||
self._timerThread.daemon = True
|
self._timerThread.daemon = True
|
||||||
self._timerThread.start()
|
self._timerThread.start()
|
||||||
|
|
||||||
def timerWorker(self):
|
def onPrintDone(self, event, payload):
|
||||||
|
Timelapse.onPrintDone(self, event, payload)
|
||||||
|
self._timerThread = None
|
||||||
|
|
||||||
|
def _timerWorker(self):
|
||||||
self._logger.debug("Starting timer for interval based timelapse")
|
self._logger.debug("Starting timer for interval based timelapse")
|
||||||
while self._inTimelapse:
|
while self._inTimelapse:
|
||||||
self.captureImage()
|
self.captureImage()
|
||||||
|
|
|
@ -345,7 +345,7 @@ class MachineCom(object):
|
||||||
STATE_CLOSED = 8
|
STATE_CLOSED = 8
|
||||||
STATE_ERROR = 9
|
STATE_ERROR = 9
|
||||||
STATE_CLOSED_WITH_ERROR = 10
|
STATE_CLOSED_WITH_ERROR = 10
|
||||||
STATE_RECEIVING_FILE = 11
|
STATE_TRANSFERING_FILE = 11
|
||||||
|
|
||||||
def __init__(self, port = None, baudrate = None, callbackObject = None):
|
def __init__(self, port = None, baudrate = None, callbackObject = None):
|
||||||
self._logger = logging.getLogger(__name__)
|
self._logger = logging.getLogger(__name__)
|
||||||
|
@ -445,8 +445,8 @@ class MachineCom(object):
|
||||||
return "Error: %s" % (self.getShortErrorString())
|
return "Error: %s" % (self.getShortErrorString())
|
||||||
if self._state == self.STATE_CLOSED_WITH_ERROR:
|
if self._state == self.STATE_CLOSED_WITH_ERROR:
|
||||||
return "Error: %s" % (self.getShortErrorString())
|
return "Error: %s" % (self.getShortErrorString())
|
||||||
if self._state == self.STATE_RECEIVING_FILE:
|
if self._state == self.STATE_TRANSFERING_FILE:
|
||||||
return "Sending file to SD"
|
return "Transfering file to SD"
|
||||||
return "?%d?" % (self._state)
|
return "?%d?" % (self._state)
|
||||||
|
|
||||||
def getShortErrorString(self):
|
def getShortErrorString(self):
|
||||||
|
@ -464,7 +464,7 @@ class MachineCom(object):
|
||||||
return self._state == self.STATE_ERROR or self._state == self.STATE_CLOSED_WITH_ERROR
|
return self._state == self.STATE_ERROR or self._state == self.STATE_CLOSED_WITH_ERROR
|
||||||
|
|
||||||
def isOperational(self):
|
def isOperational(self):
|
||||||
return self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PRINTING or self._state == self.STATE_PAUSED or self._state == self.STATE_RECEIVING_FILE
|
return self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PRINTING or self._state == self.STATE_PAUSED or self._state == self.STATE_TRANSFERING_FILE
|
||||||
|
|
||||||
def isPrinting(self):
|
def isPrinting(self):
|
||||||
return self._state == self.STATE_PRINTING
|
return self._state == self.STATE_PRINTING
|
||||||
|
@ -611,7 +611,7 @@ class MachineCom(object):
|
||||||
|
|
||||||
eventManager().fire("Error", self.getErrorString())
|
eventManager().fire("Error", self.getErrorString())
|
||||||
|
|
||||||
##~~ SD file list
|
##~~ SD file list
|
||||||
# if we are currently receiving an sd file list, each line is just a filename, so just read it and abort processing
|
# if we are currently receiving an sd file list, each line is just a filename, so just read it and abort processing
|
||||||
if self._sdFileList and not 'End file list' in line:
|
if self._sdFileList and not 'End file list' in line:
|
||||||
self._sdFiles.append(line.strip().lower())
|
self._sdFiles.append(line.strip().lower())
|
||||||
|
@ -669,6 +669,7 @@ class MachineCom(object):
|
||||||
elif 'File selected' in line:
|
elif 'File selected' in line:
|
||||||
# final answer to M23, at least on Marlin, Repetier and Sprinter: "File selected"
|
# final answer to M23, at least on Marlin, Repetier and Sprinter: "File selected"
|
||||||
self._callback.mcFileSelected(self._currentFile.getFilename(), self._currentFile.getFilesize(), True)
|
self._callback.mcFileSelected(self._currentFile.getFilename(), self._currentFile.getFilesize(), True)
|
||||||
|
eventManager().fire("FileSelected", self._currentFile.getFilename())
|
||||||
elif 'Writing to file' in line:
|
elif 'Writing to file' in line:
|
||||||
# anwer to M28, at least on Marlin, Repetier and Sprinter: "Writing to file: %s"
|
# anwer to M28, at least on Marlin, Repetier and Sprinter: "Writing to file: %s"
|
||||||
self._printSection = "CUSTOM"
|
self._printSection = "CUSTOM"
|
||||||
|
@ -676,8 +677,9 @@ class MachineCom(object):
|
||||||
elif 'Done printing file' in line:
|
elif 'Done printing file' in line:
|
||||||
# printer is reporting file finished printing
|
# printer is reporting file finished printing
|
||||||
self._sdFilePos = 0
|
self._sdFilePos = 0
|
||||||
self._changeState(self.STATE_OPERATIONAL)
|
|
||||||
self._callback.mcPrintjobDone()
|
self._callback.mcPrintjobDone()
|
||||||
|
self._changeState(self.STATE_OPERATIONAL)
|
||||||
|
eventManager().fire("PrintDone")
|
||||||
|
|
||||||
##~~ Message handling
|
##~~ Message handling
|
||||||
elif line.strip() != '' and line.strip() != 'ok' and not line.startswith("wait") and not line.startswith('Resend:') and line != 'echo:Unknown command:""\n' and self.isOperational():
|
elif line.strip() != '' and line.strip() != 'ok' and not line.startswith("wait") and not line.startswith('Resend:') and line != 'echo:Unknown command:""\n' and self.isOperational():
|
||||||
|
@ -971,10 +973,12 @@ class MachineCom(object):
|
||||||
self._sendCommand("M29")
|
self._sendCommand("M29")
|
||||||
self._currentFile = None
|
self._currentFile = None
|
||||||
self._callback.mcFileTransferDone()
|
self._callback.mcFileTransferDone()
|
||||||
|
self._changeState(self.STATE_OPERATIONAL)
|
||||||
|
eventManager().fire("TransferDone", self._currentFile.getFilename())
|
||||||
else:
|
else:
|
||||||
self._callback.mcPrintjobDone()
|
self._callback.mcPrintjobDone()
|
||||||
self._changeState(self.STATE_OPERATIONAL)
|
self._changeState(self.STATE_OPERATIONAL)
|
||||||
eventManager().fire('PrintDone')
|
eventManager().fire("PrintDone", self._currentFile.getFilename())
|
||||||
return
|
return
|
||||||
|
|
||||||
if type(line) is tuple:
|
if type(line) is tuple:
|
||||||
|
@ -1012,7 +1016,7 @@ class MachineCom(object):
|
||||||
|
|
||||||
self._printSection = "CUSTOM"
|
self._printSection = "CUSTOM"
|
||||||
self._changeState(self.STATE_PRINTING)
|
self._changeState(self.STATE_PRINTING)
|
||||||
eventManager().fire("PrintStarted")
|
eventManager().fire("PrintStarted", self._currentFile.getFilename())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._currentFile.start()
|
self._currentFile.start()
|
||||||
|
@ -1035,6 +1039,7 @@ class MachineCom(object):
|
||||||
self._currentFile.start()
|
self._currentFile.start()
|
||||||
|
|
||||||
self.sendCommand("M28 %s" % remoteFilename)
|
self.sendCommand("M28 %s" % remoteFilename)
|
||||||
|
eventManager().fire("TransferStart", remoteFilename)
|
||||||
self._callback.mcFileTransferStarted(remoteFilename, self._currentFile.getFilesize())
|
self._callback.mcFileTransferStarted(remoteFilename, self._currentFile.getFilesize())
|
||||||
|
|
||||||
def selectFile(self, filename, sd):
|
def selectFile(self, filename, sd):
|
||||||
|
@ -1048,6 +1053,7 @@ class MachineCom(object):
|
||||||
self.sendCommand("M23 %s" % filename)
|
self.sendCommand("M23 %s" % filename)
|
||||||
else:
|
else:
|
||||||
self._currentFile = PrintingGcodeFileInformation(filename)
|
self._currentFile = PrintingGcodeFileInformation(filename)
|
||||||
|
eventManager().fire("FileSelected", filename)
|
||||||
self._callback.mcFileSelected(filename, self._currentFile.getFilesize(), False)
|
self._callback.mcFileSelected(filename, self._currentFile.getFilesize(), False)
|
||||||
|
|
||||||
def cancelPrint(self):
|
def cancelPrint(self):
|
||||||
|
@ -1087,7 +1093,7 @@ class MachineCom(object):
|
||||||
if not self.isOperational() or self.isBusy():
|
if not self.isOperational() or self.isBusy():
|
||||||
return
|
return
|
||||||
|
|
||||||
self._changeState(self.STATE_RECEIVING_FILE)
|
self._changeState(self.STATE_TRANSFERING_FILE)
|
||||||
self.sendCommand("M28 %s" % filename.lower())
|
self.sendCommand("M28 %s" % filename.lower())
|
||||||
|
|
||||||
def endSdFileTransfer(self, filename):
|
def endSdFileTransfer(self, filename):
|
||||||
|
@ -1251,6 +1257,7 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
|
||||||
except Exception as (e):
|
except Exception as (e):
|
||||||
if self._filehandle is not None:
|
if self._filehandle is not None:
|
||||||
self._filehandle.close()
|
self._filehandle.close()
|
||||||
|
self._filehandle = None
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def getLineCount(self):
|
def getLineCount(self):
|
||||||
|
|
Loading…
Reference in New Issue