Added SD state evaluation and SD commands
parent
16f5e54bd7
commit
b645073f1d
|
@ -348,6 +348,11 @@ class Printer():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _getStateFlags(self):
|
def _getStateFlags(self):
|
||||||
|
if not settings().getBoolean(["feature", "sdSupport"]) or self._comm is None:
|
||||||
|
sdReady = False
|
||||||
|
else:
|
||||||
|
sdReady = self._comm.isSdReady()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"operational": self.isOperational(),
|
"operational": self.isOperational(),
|
||||||
"printing": self.isPrinting(),
|
"printing": self.isPrinting(),
|
||||||
|
@ -355,7 +360,8 @@ class Printer():
|
||||||
"error": self.isError(),
|
"error": self.isError(),
|
||||||
"loading": self.isLoading(),
|
"loading": self.isLoading(),
|
||||||
"paused": self.isPaused(),
|
"paused": self.isPaused(),
|
||||||
"ready": self.isReady()
|
"ready": self.isReady(),
|
||||||
|
"sdReady": sdReady
|
||||||
}
|
}
|
||||||
|
|
||||||
#~~ callbacks triggered from self._comm
|
#~~ callbacks triggered from self._comm
|
||||||
|
@ -434,6 +440,9 @@ class Printer():
|
||||||
|
|
||||||
self._setCurrentZ(newZ)
|
self._setCurrentZ(newZ)
|
||||||
|
|
||||||
|
def mcSdStateChange(self, sdReady):
|
||||||
|
self._stateMonitor.setState({"state": self._state, "stateString": self.getStateString(), "flags": self._getStateFlags()})
|
||||||
|
|
||||||
def mcSdFiles(self, files):
|
def mcSdFiles(self, files):
|
||||||
self._sendTriggerUpdateCallbacks("gcodeFiles")
|
self._sendTriggerUpdateCallbacks("gcodeFiles")
|
||||||
|
|
||||||
|
@ -480,6 +489,21 @@ class Printer():
|
||||||
self._sdPrintAfterSelect = printAfterSelect
|
self._sdPrintAfterSelect = printAfterSelect
|
||||||
self._comm.selectSdFile(filename)
|
self._comm.selectSdFile(filename)
|
||||||
|
|
||||||
|
def initSdCard(self):
|
||||||
|
if not self._comm:
|
||||||
|
return
|
||||||
|
self._comm.initSdCard()
|
||||||
|
|
||||||
|
def releaseSdCard(self):
|
||||||
|
if not self._comm:
|
||||||
|
return
|
||||||
|
self._comm.releaseSdCard()
|
||||||
|
|
||||||
|
def refreshSdFiles(self):
|
||||||
|
if not self._comm:
|
||||||
|
return
|
||||||
|
self._comm.refreshSdFiles()
|
||||||
|
|
||||||
#~~ callbacks triggered by sdFileStreamer
|
#~~ callbacks triggered by sdFileStreamer
|
||||||
|
|
||||||
def _onSdFileStreamProgress(self, filename, progress):
|
def _onSdFileStreamProgress(self, filename, progress):
|
||||||
|
|
|
@ -254,6 +254,23 @@ def getCustomControls():
|
||||||
customControls = settings().get(["controls"])
|
customControls = settings().get(["controls"])
|
||||||
return jsonify(controls=customControls)
|
return jsonify(controls=customControls)
|
||||||
|
|
||||||
|
@app.route(BASEURL + "control/sd", methods=["POST"])
|
||||||
|
@login_required
|
||||||
|
def sdCommand():
|
||||||
|
if not settings().getBoolean(["feature", "sdSupport"]) or not printer.isOperational() or printer.isPrinting():
|
||||||
|
return jsonify(SUCCESS)
|
||||||
|
|
||||||
|
if "command" in request.values.keys():
|
||||||
|
command = request.values["command"]
|
||||||
|
if command == "init":
|
||||||
|
printer.initSdCard()
|
||||||
|
elif command == "refresh":
|
||||||
|
printer.refreshSdFiles()
|
||||||
|
elif command == "release":
|
||||||
|
printer.releaseSdCard()
|
||||||
|
|
||||||
|
return jsonify(SUCCESS)
|
||||||
|
|
||||||
#~~ GCODE file handling
|
#~~ GCODE file handling
|
||||||
|
|
||||||
@app.route(BASEURL + "gcodefiles", methods=["GET"])
|
@app.route(BASEURL + "gcodefiles", methods=["GET"])
|
||||||
|
@ -315,6 +332,11 @@ def deleteGcodeFile():
|
||||||
gcodeManager.removeFile(filename)
|
gcodeManager.removeFile(filename)
|
||||||
return readGcodeFiles()
|
return readGcodeFiles()
|
||||||
|
|
||||||
|
@app.route(BASEURL + "gcodefiles/refresh", methods=["POST"])
|
||||||
|
def refreshFiles():
|
||||||
|
printer.updateSdFiles()
|
||||||
|
return jsonify(SUCCESS)
|
||||||
|
|
||||||
#~~ timelapse handling
|
#~~ timelapse handling
|
||||||
|
|
||||||
@app.route(BASEURL + "timelapse", methods=["GET"])
|
@app.route(BASEURL + "timelapse", methods=["GET"])
|
||||||
|
|
|
@ -111,10 +111,10 @@ body {
|
||||||
|
|
||||||
.octoprint-container {
|
.octoprint-container {
|
||||||
.accordion-heading {
|
.accordion-heading {
|
||||||
.settings-trigger {
|
.accordion-heading-button {
|
||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
.dropdown-toggle {
|
a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 8px 15px;
|
padding: 8px 15px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
|
@ -213,6 +213,7 @@ function PrinterStateViewModel(loginStateViewModel) {
|
||||||
self.isError = ko.observable(undefined);
|
self.isError = ko.observable(undefined);
|
||||||
self.isReady = ko.observable(undefined);
|
self.isReady = ko.observable(undefined);
|
||||||
self.isLoading = ko.observable(undefined);
|
self.isLoading = ko.observable(undefined);
|
||||||
|
self.isSdReady = ko.observable(undefined);
|
||||||
|
|
||||||
self.filename = ko.observable(undefined);
|
self.filename = ko.observable(undefined);
|
||||||
self.filament = ko.observable(undefined);
|
self.filament = ko.observable(undefined);
|
||||||
|
@ -268,6 +269,7 @@ function PrinterStateViewModel(loginStateViewModel) {
|
||||||
self.isError(data.flags.error);
|
self.isError(data.flags.error);
|
||||||
self.isReady(data.flags.ready);
|
self.isReady(data.flags.ready);
|
||||||
self.isLoading(data.flags.loading);
|
self.isLoading(data.flags.loading);
|
||||||
|
self.isSdReady(data.flags.sdReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
self._processJobData = function(data) {
|
self._processJobData = function(data) {
|
||||||
|
@ -756,6 +758,7 @@ function GcodeFilesViewModel(loginStateViewModel) {
|
||||||
self.isError = ko.observable(undefined);
|
self.isError = ko.observable(undefined);
|
||||||
self.isReady = ko.observable(undefined);
|
self.isReady = ko.observable(undefined);
|
||||||
self.isLoading = ko.observable(undefined);
|
self.isLoading = ko.observable(undefined);
|
||||||
|
self.isSdReady = ko.observable(undefined);
|
||||||
|
|
||||||
// initialize list helper
|
// initialize list helper
|
||||||
self.listHelper = new ItemListHelper(
|
self.listHelper = new ItemListHelper(
|
||||||
|
@ -821,6 +824,7 @@ function GcodeFilesViewModel(loginStateViewModel) {
|
||||||
self.isError(data.flags.error);
|
self.isError(data.flags.error);
|
||||||
self.isReady(data.flags.ready);
|
self.isReady(data.flags.ready);
|
||||||
self.isLoading(data.flags.loading);
|
self.isLoading(data.flags.loading);
|
||||||
|
self.isSdReady(data.flags.sdReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.requestData = function() {
|
self.requestData = function() {
|
||||||
|
@ -868,6 +872,27 @@ function GcodeFilesViewModel(loginStateViewModel) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.initSdCard = function() {
|
||||||
|
self._sendSdCommand("init");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.releaseSdCard = function() {
|
||||||
|
self._sendSdCommand("release");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.refreshSdFiles = function() {
|
||||||
|
self._sendSdCommand("refresh");
|
||||||
|
}
|
||||||
|
|
||||||
|
self._sendSdCommand = function(command) {
|
||||||
|
$.ajax({
|
||||||
|
url: AJAX_BASEURL + "control/sd",
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: {command: command}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self.getPopoverContent = function(data) {
|
self.getPopoverContent = function(data) {
|
||||||
var output = "<p><strong>Uploaded:</strong> " + data["date"] + "</p>";
|
var output = "<p><strong>Uploaded:</strong> " + data["date"] + "</p>";
|
||||||
if (data["gcodeAnalysis"]) {
|
if (data["gcodeAnalysis"]) {
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
<div class="accordion-heading">
|
<div class="accordion-heading">
|
||||||
<a class="accordion-toggle" data-toggle="collapse" href="#files"><i class="icon-list"></i> Files</a>
|
<a class="accordion-toggle" data-toggle="collapse" href="#files"><i class="icon-list"></i> Files</a>
|
||||||
|
|
||||||
<div class="settings-trigger btn-group">
|
<div class="settings-trigger accordion-heading-button btn-group">
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
<span class="icon-wrench"></span>
|
<span class="icon-wrench"></span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -149,6 +149,19 @@
|
||||||
<li><a href="#" data-bind="click: function() { $root.listHelper.toggleFilter('printed'); }"><i class="icon-ok" data-bind="style: {visibility: _.contains(listHelper.currentFilters(), 'printed') ? 'visible' : 'hidden'}"></i> Hide successfully printed files</a></li>
|
<li><a href="#" data-bind="click: function() { $root.listHelper.toggleFilter('printed'); }"><i class="icon-ok" data-bind="style: {visibility: _.contains(listHelper.currentFilters(), 'printed') ? 'visible' : 'hidden'}"></i> Hide successfully printed files</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if enableSdSupport %}
|
||||||
|
<div class="sd-trigger accordion-heading-button btn-group">
|
||||||
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
|
<span class="icon-hdd"></span>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li data-bind="visible: !isSdReady()"><a href="#" data-bind="click: function() { $root.initSdCard(); }"><i class="icon-flag"></i> Initialize SD card</a></li>
|
||||||
|
<li data-bind="visible: isSdReady()"><a href="#" data-bind="click: function() { $root.refreshSdFiles(); }"><i class="icon-refresh"></i> Refresh SD files</a></li>
|
||||||
|
<li data-bind="visible: isSdReady()"><a href="#" data-bind="click: function() { $root.releaseSdCard(); }"><i class="icon-eject"></i> Release SD card</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="accordion-body collapse in overflow_visible" id="files">
|
<div class="accordion-body collapse in overflow_visible" id="files">
|
||||||
<div class="accordion-inner">
|
<div class="accordion-inner">
|
||||||
|
|
|
@ -100,6 +100,13 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" data-bind="checked: feature_sdSupport" id="settings-featureSdSupport"> Enable SD support
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
|
@ -121,13 +128,6 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
|
||||||
<div class="controls">
|
|
||||||
<label class="checkbox">
|
|
||||||
<input type="checkbox" data-bind="checked: feature_sdSupport" id="settings-featureSdSupport"> Enable SD support
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" id="settings_folder">
|
<div class="tab-pane" id="settings_folder">
|
||||||
|
|
|
@ -57,7 +57,7 @@ def baudrateList():
|
||||||
|
|
||||||
class VirtualPrinter():
|
class VirtualPrinter():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.readList = ['start\n', 'Marlin: Virtual Marlin!\n', '\x80\n']
|
self.readList = ['start\n', 'Marlin: Virtual Marlin!\n', '\x80\n', 'SD init fail\n'] # no sd card as default startup scenario
|
||||||
self.temp = 0.0
|
self.temp = 0.0
|
||||||
self.targetTemp = 0.0
|
self.targetTemp = 0.0
|
||||||
self.lastTempAt = time.time()
|
self.lastTempAt = time.time()
|
||||||
|
@ -65,6 +65,7 @@ class VirtualPrinter():
|
||||||
self.bedTargetTemp = 1.0
|
self.bedTargetTemp = 1.0
|
||||||
|
|
||||||
self._virtualSd = settings().getBaseFolder("virtualSd")
|
self._virtualSd = settings().getBaseFolder("virtualSd")
|
||||||
|
self._sdCardReady = False
|
||||||
self._sdPrinter = None
|
self._sdPrinter = None
|
||||||
self._sdPrintingSemaphore = threading.Event()
|
self._sdPrintingSemaphore = threading.Event()
|
||||||
self._selectedSdFile = None
|
self._selectedSdFile = None
|
||||||
|
@ -104,25 +105,39 @@ class VirtualPrinter():
|
||||||
# send simulated temperature data
|
# send simulated temperature data
|
||||||
self.readList.append("ok T:%.2f /%.2f B:%.2f /%.2f @:64\n" % (self.temp, self.targetTemp, self.bedTemp, self.bedTargetTemp))
|
self.readList.append("ok T:%.2f /%.2f B:%.2f /%.2f @:64\n" % (self.temp, self.targetTemp, self.bedTemp, self.bedTargetTemp))
|
||||||
elif 'M20' in data:
|
elif 'M20' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
self._listSd()
|
self._listSd()
|
||||||
|
elif 'M21' in data:
|
||||||
|
self._sdCardReady = True
|
||||||
|
self.readList.append("SD card ok")
|
||||||
|
elif 'M22' in data:
|
||||||
|
self._sdCardReady = False
|
||||||
elif 'M23' in data:
|
elif 'M23' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
filename = data.split(None, 1)[1].strip()
|
filename = data.split(None, 1)[1].strip()
|
||||||
self._selectSdFile(filename)
|
self._selectSdFile(filename)
|
||||||
elif 'M24' in data:
|
elif 'M24' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
self._startSdPrint()
|
self._startSdPrint()
|
||||||
elif 'M25' in data:
|
elif 'M25' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
self._pauseSdPrint()
|
self._pauseSdPrint()
|
||||||
elif 'M26' in data:
|
elif 'M26' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
pos = int(re.search("S([0-9]+)", data).group(1))
|
pos = int(re.search("S([0-9]+)", data).group(1))
|
||||||
self._setSdPos(pos)
|
self._setSdPos(pos)
|
||||||
elif 'M27' in data:
|
elif 'M27' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
self._reportSdStatus()
|
self._reportSdStatus()
|
||||||
elif 'M28' in data:
|
elif 'M28' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
filename = data.split(None, 1)[1].strip()
|
filename = data.split(None, 1)[1].strip()
|
||||||
self._writeSdFile(filename)
|
self._writeSdFile(filename)
|
||||||
elif 'M29' in data:
|
elif 'M29' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
self._finishSdFile()
|
self._finishSdFile()
|
||||||
elif 'M30' in data:
|
elif 'M30' in data:
|
||||||
|
if self._sdCardReady:
|
||||||
filename = data.split(None, 1)[1].strip()
|
filename = data.split(None, 1)[1].strip()
|
||||||
self._deleteSdFile(filename)
|
self._deleteSdFile(filename)
|
||||||
elif "M110" in data:
|
elif "M110" in data:
|
||||||
|
@ -196,7 +211,7 @@ class VirtualPrinter():
|
||||||
|
|
||||||
def _sdPrintingWorker(self):
|
def _sdPrintingWorker(self):
|
||||||
self._selectedSdFilePos = 0
|
self._selectedSdFilePos = 0
|
||||||
with open(self._selectedSdFile, "rb") as f:
|
with open(self._selectedSdFile, "r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
# reset position if requested by client
|
# reset position if requested by client
|
||||||
if self._newSdFilePos is not None:
|
if self._newSdFilePos is not None:
|
||||||
|
@ -284,6 +299,9 @@ class MachineComPrintCallback(object):
|
||||||
def mcZChange(self, newZ):
|
def mcZChange(self, newZ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def mcSdStateChange(self, sdReady):
|
||||||
|
pass
|
||||||
|
|
||||||
def mcSdFiles(self, files):
|
def mcSdFiles(self, files):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -355,6 +373,7 @@ class MachineCom(object):
|
||||||
self.thread.daemon = True
|
self.thread.daemon = True
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
|
self._sdAvailable = False
|
||||||
self._sdPrinting = False
|
self._sdPrinting = False
|
||||||
self._sdFileList = False
|
self._sdFileList = False
|
||||||
self._sdFile = None
|
self._sdFile = None
|
||||||
|
@ -443,6 +462,9 @@ class MachineCom(object):
|
||||||
def isBusy(self):
|
def isBusy(self):
|
||||||
return self.isPrinting() or self._state == self.STATE_RECEIVING_FILE
|
return self.isPrinting() or self._state == self.STATE_RECEIVING_FILE
|
||||||
|
|
||||||
|
def isSdReady(self):
|
||||||
|
return self._sdAvailable
|
||||||
|
|
||||||
def getPrintPos(self):
|
def getPrintPos(self):
|
||||||
if self._sdPrinting:
|
if self._sdPrinting:
|
||||||
return self._sdFilePos
|
return self._sdFilePos
|
||||||
|
@ -462,10 +484,11 @@ class MachineCom(object):
|
||||||
if self._sdPrinting:
|
if self._sdPrinting:
|
||||||
printTime = (time.time() - self._printStartTime) / 60
|
printTime = (time.time() - self._printStartTime) / 60
|
||||||
if self._sdFilePos > 0:
|
if self._sdFilePos > 0:
|
||||||
printTimeTotal = printTime * (self._sdFileSize / self._sdFilePos)
|
printTimeTotal = printTime * self._sdFileSize / self._sdFilePos
|
||||||
else:
|
else:
|
||||||
printTimeTotal = printTime * self._sdFileSize
|
printTimeTotal = printTime * self._sdFileSize
|
||||||
printTimeLeft = printTimeTotal - printTime
|
printTimeLeft = printTimeTotal - printTime
|
||||||
|
self._logger.info("printTime: %f, sdFileSize: %f, sdFilePos: %f, printTimeTotal: %f, printTimeLeft: %f" % (printTime, self._sdFileSize, self._sdFilePos, printTimeTotal, printTimeLeft))
|
||||||
return printTimeLeft
|
return printTimeLeft
|
||||||
else:
|
else:
|
||||||
# for host printing we only start counting the print time at gcode line 100, so we need to calculate stuff
|
# for host printing we only start counting the print time at gcode line 100, so we need to calculate stuff
|
||||||
|
@ -593,6 +616,14 @@ class MachineCom(object):
|
||||||
self._heatupWaitStartTime = t
|
self._heatupWaitStartTime = t
|
||||||
|
|
||||||
##~~ SD Card handling
|
##~~ SD Card handling
|
||||||
|
elif 'SD init fail' in line:
|
||||||
|
self._sdAvailable = False
|
||||||
|
self._sdFiles = []
|
||||||
|
self._callback.mcSdStateChange(self._sdAvailable)
|
||||||
|
elif 'SD card ok' in line:
|
||||||
|
self._sdAvailable = True
|
||||||
|
self.refreshSdFiles()
|
||||||
|
self._callback.mcSdStateChange(self._sdAvailable)
|
||||||
elif 'Begin file list' in line:
|
elif 'Begin file list' in line:
|
||||||
self._sdFiles = []
|
self._sdFiles = []
|
||||||
self._sdFileList = True
|
self._sdFileList = True
|
||||||
|
@ -671,8 +702,6 @@ class MachineCom(object):
|
||||||
startSeen = True
|
startSeen = True
|
||||||
elif "ok" in line and startSeen:
|
elif "ok" in line and startSeen:
|
||||||
self._changeState(self.STATE_OPERATIONAL)
|
self._changeState(self.STATE_OPERATIONAL)
|
||||||
if settings().get(["feature", "sdSupport"]):
|
|
||||||
self._sendCommand("M20")
|
|
||||||
elif time.time() > timeout:
|
elif time.time() > timeout:
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
@ -697,19 +726,23 @@ class MachineCom(object):
|
||||||
self._log("Communication timeout during printing, forcing a line")
|
self._log("Communication timeout during printing, forcing a line")
|
||||||
line = 'ok'
|
line = 'ok'
|
||||||
|
|
||||||
|
if self._sdPrinting:
|
||||||
|
if time.time() > tempRequestTimeout:
|
||||||
|
self._sendCommand("M105")
|
||||||
|
tempRequestTimeout = time.time() + 5
|
||||||
|
|
||||||
|
if time.time() > sdStatusRequestTimeout:
|
||||||
|
self._sendCommand("M27")
|
||||||
|
sdStatusRequestTimeout = time.time() + 1
|
||||||
|
|
||||||
|
if 'ok' or 'SD printing byte' in line:
|
||||||
|
timeout = time.time() + 5
|
||||||
|
else:
|
||||||
# Even when printing request the temperature every 5 seconds.
|
# Even when printing request the temperature every 5 seconds.
|
||||||
if time.time() > tempRequestTimeout:
|
if time.time() > tempRequestTimeout:
|
||||||
self._commandQueue.put("M105")
|
self._commandQueue.put("M105")
|
||||||
tempRequestTimeout = time.time() + 5
|
tempRequestTimeout = time.time() + 5
|
||||||
|
|
||||||
if self._sdPrinting:
|
|
||||||
if time.time() > sdStatusRequestTimeout:
|
|
||||||
self._commandQueue.put("M27")
|
|
||||||
sdStatusRequestTimeout = time.time() + 1
|
|
||||||
|
|
||||||
if 'ok' in line and not self._commandQueue.empty():
|
|
||||||
self._sendCommand(self._commandQueue.get())
|
|
||||||
else:
|
|
||||||
if 'ok' in line:
|
if 'ok' in line:
|
||||||
timeout = time.time() + 5
|
timeout = time.time() + 5
|
||||||
if self._resendDelta is not None:
|
if self._resendDelta is not None:
|
||||||
|
@ -908,7 +941,7 @@ class MachineCom(object):
|
||||||
self._log("Unexpected error: %s" % (getExceptionString()))
|
self._log("Unexpected error: %s" % (getExceptionString()))
|
||||||
self._sendCommand(line, True)
|
self._sendCommand(line, True)
|
||||||
self._gcodePos += 1
|
self._gcodePos += 1
|
||||||
self._callback.mcProgress(self._gcodePos)
|
self._callback.mcProgress()
|
||||||
|
|
||||||
def sendCommand(self, cmd):
|
def sendCommand(self, cmd):
|
||||||
cmd = cmd.encode('ascii', 'replace')
|
cmd = cmd.encode('ascii', 'replace')
|
||||||
|
@ -929,14 +962,6 @@ class MachineCom(object):
|
||||||
self._printStartTime = time.time()
|
self._printStartTime = time.time()
|
||||||
self._sendNext()
|
self._sendNext()
|
||||||
|
|
||||||
def selectSdFile(self, filename):
|
|
||||||
if not self.isOperational() or self.isPrinting():
|
|
||||||
return
|
|
||||||
self._sdFile = None
|
|
||||||
self._sdFilePos = 0
|
|
||||||
|
|
||||||
self.sendCommand("M23 %s" % filename.lower())
|
|
||||||
|
|
||||||
def printSdFile(self):
|
def printSdFile(self):
|
||||||
if not self.isOperational() or self.isPrinting():
|
if not self.isOperational() or self.isPrinting():
|
||||||
return
|
return
|
||||||
|
@ -979,24 +1004,64 @@ class MachineCom(object):
|
||||||
result.update(self._feedRateModifier)
|
result.update(self._feedRateModifier)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
##~~ SD card
|
||||||
def getSdFiles(self):
|
def getSdFiles(self):
|
||||||
return self._sdFiles
|
return self._sdFiles
|
||||||
|
|
||||||
def startSdFileTransfer(self, filename):
|
def startSdFileTransfer(self, filename):
|
||||||
if self.isPrinting() or self.isPaused():
|
if not self.isOperational() or self.isPrinting() or self.isPaused():
|
||||||
return
|
return
|
||||||
|
|
||||||
self._changeState(self.STATE_RECEIVING_FILE)
|
self._changeState(self.STATE_RECEIVING_FILE)
|
||||||
self.sendCommand("M28 %s" % filename.lower())
|
self.sendCommand("M28 %s" % filename.lower())
|
||||||
|
|
||||||
def endSdFileTransfer(self, filename):
|
def endSdFileTransfer(self, filename):
|
||||||
|
if not self.isOperational() or self.isPrinting() or self.isPaused():
|
||||||
|
return
|
||||||
|
|
||||||
self.sendCommand("M29 %s" % filename.lower())
|
self.sendCommand("M29 %s" % filename.lower())
|
||||||
self._changeState(self.STATE_OPERATIONAL)
|
self._changeState(self.STATE_OPERATIONAL)
|
||||||
self.sendCommand("M20")
|
self.refreshSdFiles()
|
||||||
|
|
||||||
|
def selectSdFile(self, filename):
|
||||||
|
if not self.isOperational() or self.isPrinting() or self.isPaused():
|
||||||
|
return
|
||||||
|
|
||||||
|
self._sdFile = None
|
||||||
|
self._sdFilePos = 0
|
||||||
|
|
||||||
|
self.sendCommand("M23 %s" % filename.lower())
|
||||||
|
|
||||||
def deleteSdFile(self, filename):
|
def deleteSdFile(self, filename):
|
||||||
|
if not self.isOperational() or ((self.isPrinting() or self.isPaused()) and self._sdFile == filename.lower()):
|
||||||
|
# do not delete a file from sd we are currently printing from
|
||||||
|
return
|
||||||
|
|
||||||
self.sendCommand("M30 %s" % filename.lower())
|
self.sendCommand("M30 %s" % filename.lower())
|
||||||
|
self.refreshSdFiles()
|
||||||
|
|
||||||
|
def refreshSdFiles(self):
|
||||||
|
if not self.isOperational() or self.isPrinting() or self.isPaused():
|
||||||
|
return
|
||||||
self.sendCommand("M20")
|
self.sendCommand("M20")
|
||||||
|
|
||||||
|
def initSdCard(self):
|
||||||
|
if not self.isOperational():
|
||||||
|
return
|
||||||
|
self.sendCommand("M21")
|
||||||
|
|
||||||
|
def releaseSdCard(self):
|
||||||
|
if not self.isOperational() or ((self.isPrinting() or self.isPaused()) and self._sdPrinting):
|
||||||
|
# do not release the sd card if we are currently printing from it
|
||||||
|
return
|
||||||
|
|
||||||
|
self.sendCommand("M22")
|
||||||
|
self._sdAvailable = False
|
||||||
|
self._sdFiles = []
|
||||||
|
|
||||||
|
self._callback.mcSdStateChange(self._sdAvailable)
|
||||||
|
self._callback.mcSdFiles(self._sdFiles)
|
||||||
|
|
||||||
def getExceptionString():
|
def getExceptionString():
|
||||||
locationInfo = traceback.extract_tb(sys.exc_info()[2])[0]
|
locationInfo = traceback.extract_tb(sys.exc_info()[2])[0]
|
||||||
return "%s: '%s' @ %s:%s:%d" % (str(sys.exc_info()[0].__name__), str(sys.exc_info()[1]), os.path.basename(locationInfo[0]), locationInfo[2], locationInfo[1])
|
return "%s: '%s' @ %s:%s:%d" % (str(sys.exc_info()[0].__name__), str(sys.exc_info()[1]), os.path.basename(locationInfo[0]), locationInfo[2], locationInfo[1])
|
||||||
|
|
Loading…
Reference in New Issue