Merge branch 'devel' into nullie-circular-beds

This commit is contained in:
Gina Häußge 2014-03-22 20:39:42 +01:00
commit ba7d0a60e4
13 changed files with 146 additions and 66 deletions

View file

@ -1 +1 @@
1.1.0-dev
1.2.0-dev

8
run
View file

@ -1,13 +1,5 @@
#!/usr/bin/env python
print """
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! You are using an old startup method for OctoPrint. !!!
!!! Please perform 'sudo python setup.py install' and !!!
!!! use the 'octoprint' executable instead. !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"""
import os
import sys

View file

@ -613,11 +613,12 @@ class Printer():
"target": self._temp[tool][1],
"offset": tempOffset[tool] if tool in tempOffset.keys() and tempOffset[tool] is not None else 0
}
result["bed"] = {
"actual": self._bedTemp[0],
"target": self._bedTemp[1],
"offset": bedTempOffset
}
if self._bedTemp is not None:
result["bed"] = {
"actual": self._bedTemp[0],
"target": self._bedTemp[1],
"offset": bedTempOffset
}
return result

View file

@ -59,6 +59,7 @@ def getSettings():
"waitForStart": s.getBoolean(["feature", "waitForStartOnConnect"]),
"alwaysSendChecksum": s.getBoolean(["feature", "alwaysSendChecksum"]),
"sdSupport": s.getBoolean(["feature", "sdSupport"]),
"sdAlwaysAvailable": s.getBoolean(["feature", "sdAlwaysAvailable"]),
"swallowOkAfterResend": s.getBoolean(["feature", "swallowOkAfterResend"]),
"repetierTargetTemp": s.getBoolean(["feature", "repetierTargetTemp"])
},
@ -71,6 +72,8 @@ def getSettings():
"timeoutConnection": s.getFloat(["serial", "timeout", "connection"]),
"timeoutDetection": s.getFloat(["serial", "timeout", "detection"]),
"timeoutCommunication": s.getFloat(["serial", "timeout", "communication"]),
"timeoutTemperature": s.getFloat(["serial", "timeout", "temperature"]),
"timeoutSdStatus": s.getFloat(["serial", "timeout", "sdStatus"]),
"log": s.getBoolean(["serial", "log"])
},
"folder": {
@ -136,6 +139,7 @@ def setSettings():
if "waitForStart" in data["feature"].keys(): s.setBoolean(["feature", "waitForStartOnConnect"], data["feature"]["waitForStart"])
if "alwaysSendChecksum" in data["feature"].keys(): s.setBoolean(["feature", "alwaysSendChecksum"], data["feature"]["alwaysSendChecksum"])
if "sdSupport" in data["feature"].keys(): s.setBoolean(["feature", "sdSupport"], data["feature"]["sdSupport"])
if "sdAlwaysAvailable" in data["feature"].keys(): s.setBoolean(["feature", "sdAlwaysAvailable"], data["feature"]["sdAlwaysAvailable"])
if "swallowOkAfterResend" in data["feature"].keys(): s.setBoolean(["feature", "swallowOkAfterResend"], data["feature"]["swallowOkAfterResend"])
if "repetierTargetTemp" in data["feature"].keys(): s.setBoolean(["feature", "repetierTargetTemp"], data["feature"]["repetierTargetTemp"])
@ -146,6 +150,8 @@ def setSettings():
if "timeoutConnection" in data["serial"].keys(): s.setFloat(["serial", "timeout", "connection"], data["serial"]["timeoutConnection"])
if "timeoutDetection" in data["serial"].keys(): s.setFloat(["serial", "timeout", "detection"], data["serial"]["timeoutDetection"])
if "timeoutCommunication" in data["serial"].keys(): s.setFloat(["serial", "timeout", "communication"], data["serial"]["timeoutCommunication"])
if "timeoutTemperature" in data["serial"].keys(): s.setFloat(["serial", "timeout", "temperature"], data["serial"]["timeoutTemperature"])
if "timeoutSdStatus" in data["serial"].keys(): s.setFloat(["serial", "timeout", "sdStatus"], data["serial"]["timeoutSdStatus"])
oldLog = s.getBoolean(["serial", "log"])
if "log" in data["serial"].keys(): s.setBoolean(["serial", "log"], data["serial"]["log"])

View file

@ -31,7 +31,9 @@ default_settings = {
"timeout": {
"detection": 0.5,
"connection": 2,
"communication": 5
"communication": 5,
"temperature": 5,
"sdStatus": 1
},
"additionalPorts": []
},
@ -66,6 +68,7 @@ default_settings = {
"waitForStartOnConnect": False,
"alwaysSendChecksum": False,
"sdSupport": True,
"sdAlwaysAvailable": False,
"swallowOkAfterResend": True,
"repetierTargetTemp": False
},
@ -146,7 +149,8 @@ default_settings = {
"okWithLinenumber": False,
"numExtruders": 1,
"includeCurrentToolInTemps": True,
"hasBed": True
"hasBed": True,
"repetierStyleTargetTemperature": False
}
}
}

View file

@ -407,14 +407,15 @@ GCODE.renderer = (function(){
var applyZoom = function(mdlInfo) {
var pt = ctx.transformedPoint(canvas.width/2,canvas.height/2);
var transform = ctx.getTransform();
var scaleF;
if (scaleX && scaleY && transform.a && transform.d) {
ctx.translate(pt.x, pt.y);
ctx.scale(1 / scaleX, 1 / scaleY);
ctx.translate(-pt.x, -pt.y);
transform = ctx.getTransform();
}
if (mdlInfo && renderOptions["zoomInOnModel"]) {
scaleF = mdlInfo.modelSize.x > mdlInfo.modelSize.y ? (canvas.width - 10) / mdlInfo.modelSize.x : (canvas.height - 10) / mdlInfo.modelSize.y;
var scaleF = mdlInfo.modelSize.x > mdlInfo.modelSize.y ? (canvas.width - 10) / mdlInfo.modelSize.x : (canvas.height - 10) / mdlInfo.modelSize.y;
scaleF /= zoomFactor;
if (transform.a && transform.d) {
scaleX = scaleF / transform.a;
@ -451,10 +452,11 @@ GCODE.renderer = (function(){
var mustRefresh = false;
var dirty = false;
for (var opt in options) {
if (!options.hasOwnProperty(opt)) continue;
if (!renderOptions.hasOwnProperty(opt) || !options.hasOwnProperty(opt)) continue;
if (options[opt] === undefined) continue;
if (renderOptions[opt] == options[opt]) continue;
dirty = dirty || (renderOptions[opt] != options[opt]);
dirty = true;
renderOptions[opt] = options[opt];
if ($.inArray(opt, ["moveModel", "centerViewport", "zoomInOnModel", "bed"])) {
mustRefresh = true;

View file

@ -42,6 +42,7 @@ function DataUpdater(loginStateViewModel, connectionViewModel, printerStateViewM
$("#offline_overlay").hide();
self.logViewModel.requestData();
self.timelapseViewModel.requestData();
$("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime());
self.loginStateViewModel.requestData();
self.gcodeFilesViewModel.requestData();
self.gcodeViewModel.reset();

View file

@ -101,6 +101,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.feature_waitForStart = ko.observable(undefined);
self.feature_alwaysSendChecksum = ko.observable(undefined);
self.feature_sdSupport = ko.observable(undefined);
self.feature_sdAlwaysAvailable = ko.observable(undefined);
self.feature_swallowOkAfterResend = ko.observable(undefined);
self.feature_repetierTargetTemp = ko.observable(undefined);
@ -112,6 +113,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.serial_timeoutConnection = ko.observable(undefined);
self.serial_timeoutDetection = ko.observable(undefined);
self.serial_timeoutCommunication = ko.observable(undefined);
self.serial_timeoutTemperature = ko.observable(undefined);
self.serial_timeoutSdStatus = ko.observable(undefined);
self.serial_log = ko.observable(undefined);
self.folder_uploads = ko.observable(undefined);
@ -211,6 +214,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.feature_waitForStart(response.feature.waitForStart);
self.feature_alwaysSendChecksum(response.feature.alwaysSendChecksum);
self.feature_sdSupport(response.feature.sdSupport);
self.feature_sdAlwaysAvailable(response.feature.sdAlwaysAvailable);
self.feature_swallowOkAfterResend(response.feature.swallowOkAfterResend);
self.feature_repetierTargetTemp(response.feature.repetierTargetTemp);
@ -222,6 +226,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.serial_timeoutConnection(response.serial.timeoutConnection);
self.serial_timeoutDetection(response.serial.timeoutDetection);
self.serial_timeoutCommunication(response.serial.timeoutCommunication);
self.serial_timeoutTemperature(response.serial.timeoutTemperature);
self.serial_timeoutSdStatus(response.serial.timeoutSdStatus);
self.serial_log(response.serial.log);
self.folder_uploads(response.folder.uploads);
@ -275,6 +281,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
"waitForStart": self.feature_waitForStart(),
"alwaysSendChecksum": self.feature_alwaysSendChecksum(),
"sdSupport": self.feature_sdSupport(),
"sdAlwaysAvailable": self.feature_sdAlwaysAvailable(),
"swallowOkAfterResend": self.feature_swallowOkAfterResend(),
"repetierTargetTemp": self.feature_repetierTargetTemp()
},
@ -285,6 +292,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
"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": {

View file

@ -267,7 +267,7 @@
<table class="table table-bordered table-hover" style="table-layout: fixed; width: 100%; margin-top: 20px">
<tr>
<th style="width: 18%"></th>
<th style="text-align: right" style="width: 12%">Actual</th>
<th style="width: 12%; text-align: right">Actual</th>
<th style="width: 35%">Target</th>
<th style="width: 35%">Offset</th>
</tr>

View file

@ -46,7 +46,7 @@
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-movementSpeedE">Communication timeout</label>
<label class="control-label" for="settings-serialTimeoutCommunication">Communication timeout</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutCommunication" id="settings-serialTimeoutCommunication">
@ -55,7 +55,25 @@
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-movementSpeedE">Connection timeout</label>
<label class="control-label" for="settings-movementSpeedE">Temperature timeout</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutTemperature" id="settings-serialTimeoutTemperature">
<span class="add-on">s</span>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-serialTimeoutSdStatus">SD status timeout</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutSdStatus" id="settings-serialTimeoutSdStatus">
<span class="add-on">s</span>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-serialTimeoutConnection">Connection timeout</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutConnection" id="settings-serialTimeoutConnection">
@ -64,7 +82,7 @@
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-movementSpeedE">Autodetection timeout</label>
<label class="control-label" for="settings-serialTimeoutDetection">Autodetection timeout</label>
<div class="controls">
<div class="input-append">
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutDetection" id="settings-serialTimeoutDetection">
@ -245,6 +263,13 @@
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_sdAlwaysAvailable" id="settings-featureSdAlwaysAvailable"> Always assume SD card is present <span class="label">Repetier</span>
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">

View file

@ -10,7 +10,7 @@ import re
import tempfile
from flask import make_response
from octoprint.settings import settings
from octoprint.settings import settings, default_settings
def getFormattedSize(num):
@ -89,8 +89,9 @@ def getGitInfo():
def getNewTimeout(type):
now = time.time()
if type not in ["connection", "detection", "communication"]:
return now # timeout immediately for unknown timeout type
if type not in default_settings["serial"]["timeout"].keys():
# timeout immediately for unknown timeout type
return now
return now + settings().getFloat(["serial", "timeout", type])

View file

@ -522,6 +522,10 @@ class MachineCom(object):
if not self.isOperational():
return
self.sendCommand("M21")
if settings().getBoolean(["feature", "sdAlwaysAvailable"]):
self._sdAvailable = True
self.refreshSdFiles()
self._callback.mcSdStateChange(self._sdAvailable)
def releaseSdCard(self):
if not self.isOperational() or (self.isBusy() and self.isSdFileSelected()):
@ -569,7 +573,14 @@ class MachineCom(object):
if not "T0" in parsedTemps.keys() and "T" in parsedTemps.keys():
# only single reporting, "T" is our one and only extruder temperature
toolNum, actual, target = parsedTemps["T"]
self._temp[0] = (actual, target)
if target is not None:
self._temp[0] = (actual, target)
elif 0 in self._temp.keys() and self._temp[0] is not None and isinstance(self._temp[0], tuple):
(oldActual, oldTarget) = self._temp[0]
self._temp[0] = (actual, oldTarget)
else:
self._temp[0] = (actual, None)
elif "T0" in parsedTemps.keys():
for n in range(maxToolNum + 1):
tool = "T%d" % n
@ -614,8 +625,8 @@ class MachineCom(object):
#Start monitoring the serial port.
timeout = getNewTimeout("communication")
tempRequestTimeout = timeout
sdStatusRequestTimeout = timeout
tempRequestTimeout = getNewTimeout("temperature")
sdStatusRequestTimeout = getNewTimeout("sdStatus")
startSeen = not settings().getBoolean(["feature", "waitForStartOnConnect"])
heatingUp = False
swallowOk = False
@ -626,6 +637,8 @@ class MachineCom(object):
line = self._readline()
if line is None:
break
if line.strip() is not "":
timeout = getNewTimeout("communication")
##~~ Error handling
line = self._handleErrors(line)
@ -690,7 +703,7 @@ class MachineCom(object):
# something went wrong, printer is reporting that we actually are not printing right now...
self._sdFilePos = 0
self._changeState(self.STATE_OPERATIONAL)
elif 'SD card ok' in line:
elif 'SD card ok' in line and not self._sdAvailable:
self._sdAvailable = True
self.refreshSdFiles()
self._callback.mcSdStateChange(self._sdAvailable)
@ -702,7 +715,7 @@ class MachineCom(object):
self._callback.mcSdFiles(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("([0-9]*)/([0-9]*)", line)
match = self._regex_sdPrintingByte.search(line)
self._currentFile.setFilepos(int(match.group(1)))
self._callback.mcProgress()
elif 'File opened' in line:
@ -719,6 +732,7 @@ class MachineCom(object):
})
elif 'Writing to file' in line:
# anwer to M28, at least on Marlin, Repetier and Sprinter: "Writing to file: %s"
self._printSection = "CUSTOM"
self._changeState(self.STATE_PRINTING)
line = "ok"
elif 'Done printing file' in line:
@ -817,6 +831,8 @@ class MachineCom(object):
self._changeState(self.STATE_OPERATIONAL)
if self._sdAvailable:
self.refreshSdFiles()
else:
self.initSdCard()
eventManager().fire(Events.CONNECTED, {"port": self._port, "baudrate": self._baudrate})
else:
self._testingBaudrate = False
@ -829,7 +845,9 @@ class MachineCom(object):
startSeen = True
elif "ok" in line and startSeen:
self._changeState(self.STATE_OPERATIONAL)
if not self._sdAvailable:
if self._sdAvailable:
self.refreshSdFiles()
else:
self.initSdCard()
eventManager().fire(Events.CONNECTED, {"port": self._port, "baudrate": self._baudrate})
elif time.time() > timeout:
@ -845,7 +863,7 @@ class MachineCom(object):
self._sendCommand(self._commandQueue.get())
else:
self._sendCommand("M105")
tempRequestTimeout = getNewTimeout("communication")
tempRequestTimeout = getNewTimeout("temperature")
# resend -> start resend procedure from requested line
elif line.lower().startswith("resend") or line.lower().startswith("rs"):
if settings().get(["feature", "swallowOkAfterResend"]):
@ -861,24 +879,20 @@ class MachineCom(object):
if self.isSdPrinting():
if time.time() > tempRequestTimeout and not heatingUp:
self._sendCommand("M105")
tempRequestTimeout = getNewTimeout("communication")
tempRequestTimeout = getNewTimeout("temperature")
if time.time() > sdStatusRequestTimeout and not heatingUp:
self._sendCommand("M27")
sdStatusRequestTimeout = time.time() + 1
if 'ok' or 'SD printing byte' in line:
timeout = getNewTimeout("communication")
sdStatusRequestTimeout = getNewTimeout("sdStatus")
else:
# Even when printing request the temperature every 5 seconds.
if time.time() > tempRequestTimeout and not self.isStreaming():
self._commandQueue.put("M105")
tempRequestTimeout = getNewTimeout("communication")
tempRequestTimeout = getNewTimeout("temperature")
if "ok" in line and swallowOk:
swallowOk = False
elif "ok" in line:
timeout = getNewTimeout("communication")
if self._resendDelta is not None:
self._resendNextCommand()
elif not self._commandQueue.empty() and not self.isStreaming():

View file

@ -58,6 +58,7 @@ class VirtualPrinter():
linenumber = int(re.search("N([0-9]+)", data).group(1))
self.lastN = linenumber
self.currentLine = linenumber
self._sendOk()
return
elif data.startswith("N"):
linenumber = int(re.search("N([0-9]+)", data).group(1))
@ -91,29 +92,15 @@ class VirtualPrinter():
#print "Send: %s" % (data.rstrip())
if 'M104' in data or 'M109' in data:
if not self._parseHotendCommand(data):
return
self._parseHotendCommand(data)
return
if 'M140' in data or 'M190' in data:
if not self._parseBedCommand(data):
return
self._parseBedCommand(data)
return
if 'M105' in data:
# send simulated temperature data
if settings().getInt(["devel", "virtualPrinter", "numExtruders"]) > 1:
allTemps = []
for i in range(len(self.temp)):
allTemps.append((i, self.temp[i], self.targetTemp[i]))
allTempsString = " ".join(map(lambda x: "T%d:%.2f /%.2f" % x, allTemps))
if settings().getBoolean(["devel", "virtualPrinter", "hasBed"]):
allTempsString = "B:%.2f /%.2f %s" % (self.bedTemp, self.bedTargetTemp, allTempsString)
if settings().getBoolean(["devel", "virtualPrinter", "includeCurrentToolInTemps"]):
self.readList.append("ok T:%.2f /%.2f %s @:64\n" % (self.temp[self.currentExtruder], self.targetTemp[self.currentExtruder] + 1))
else:
self.readList.append("ok %s @:64\n" % allTempsString)
else:
self.readList.append("ok T:%.2f /%.2f B:%.2f /%.2f @:64\n" % (self.temp[0], self.targetTemp[0], self.bedTemp, self.bedTargetTemp))
self._processTemperatureQuery()
elif 'M20' in data:
if self._sdCardReady:
self._listSd()
@ -204,6 +191,35 @@ class VirtualPrinter():
else:
self.readList.append("Not SD printing")
def _processTemperatureQuery(self):
includeTarget = not settings().getBoolean(["devel", "virtualPrinter", "repetierStyleTargetTemperature"])
# send simulated temperature data
if settings().getInt(["devel", "virtualPrinter", "numExtruders"]) > 1:
allTemps = []
for i in range(len(self.temp)):
allTemps.append((i, self.temp[i], self.targetTemp[i]))
allTempsString = " ".join(map(lambda x: "T%d:%.2f /%.2f" % x if includeTarget else "T%d:%.2f" % (x[0], x[1]), allTemps))
if settings().getBoolean(["devel", "virtualPrinter", "hasBed"]):
if includeTarget:
allTempsString = "B:%.2f /%.2f %s" % (self.bedTemp, self.bedTargetTemp, allTempsString)
else:
allTempsString = "B:%.2f %s" % (self.bedTemp, allTempsString)
if settings().getBoolean(["devel", "virtualPrinter", "includeCurrentToolInTemps"]):
if includeTarget:
self.readList.append("ok T:%.2f /%.2f %s @:64\n" % (self.temp[self.currentExtruder], self.targetTemp[self.currentExtruder] + 1, allTempsString))
else:
self.readList.append("ok T:%.2f %s @:64\n" % (self.temp[self.currentExtruder], allTempsString))
else:
self.readList.append("ok %s @:64\n" % allTempsString)
else:
if includeTarget:
self.readList.append("ok T:%.2f /%.2f B:%.2f /%.2f @:64\n" % (self.temp[0], self.targetTemp[0], self.bedTemp, self.bedTargetTemp))
else:
self.readList.append("ok T:%.2f B:%.2f @:64\n" % (self.temp[0], self.bedTemp))
def _parseHotendCommand(self, line):
tool = 0
toolMatch = re.search('T([0-9]+)', line)
@ -214,6 +230,7 @@ class VirtualPrinter():
pass
if tool >= settings().getInt(["devel", "virtualPrinter", "numExtruders"]):
self._sendOk()
return
try:
@ -224,8 +241,12 @@ class VirtualPrinter():
if "M109" in line:
self._heatupThread = threading.Thread(target=self._waitForHeatup, args=["tool%d" % tool])
self._heatupThread.start()
return False
return True
return
self._sendOk()
if settings().getBoolean(["devel", "virtualPrinter", "repetierStyleTargetTemperature"]):
self.readList.append("TargetExtr%d:%d" % (tool, self.targetTemp[tool]))
def _parseBedCommand(self, line):
try:
@ -236,8 +257,12 @@ class VirtualPrinter():
if "M190" in line:
self._heatupThread = threading.Thread(target=self._waitForHeatup, args=["bed"])
self._heatupThread.start()
return False
return True
return
self._sendOk()
if settings().getBoolean(["devel", "virtualPrinter", "repetierStyleTargetTemperature"]):
self.readList.append("TargetBed:%d" % self.bedTargetTemp)
def _writeSdFile(self, filename):
file = os.path.join(self._virtualSd, filename).lower()
@ -260,7 +285,7 @@ class VirtualPrinter():
def _sdPrintingWorker(self):
self._selectedSdFilePos = 0
with open(self._selectedSdFile, "r") as f:
for line in f:
for line in iter(f.readline, ""):
# reset position if requested by client
if self._newSdFilePos is not None:
f.seek(self._newSdFilePos)