Merge branch 'devel' into gcodestreaming

Conflicts:
	octoprint/printer.py
	octoprint/static/js/ui.js
	octoprint/templates/index.jinja2
	octoprint/util/comm.py
master
Gina Häußge 2013-06-09 18:28:40 +02:00
commit 8be1329a71
9 changed files with 302 additions and 130 deletions

View File

@ -177,7 +177,7 @@ class Printer():
if self._selectedFile is None: if self._selectedFile is None:
return return
self._setCurrentZ(-1) self._setCurrentZ(None)
self._comm.startPrint() self._comm.startPrint()
def togglePausePrint(self): def togglePausePrint(self):

View File

@ -43,7 +43,7 @@ default_settings = {
"waitForWaitOnConnect": False, "waitForWaitOnConnect": False,
"alwaysSendChecksum": False, "alwaysSendChecksum": False,
"resetLineNumbersWithPrefixedN": False, "resetLineNumbersWithPrefixedN": False,
"sdSupport": False "sdSupport": True
}, },
"folder": { "folder": {
"uploads": None, "uploads": None,

View File

@ -223,42 +223,31 @@
var assumeNonDC = false; var assumeNonDC = false;
for(var i=0;i<gcode.length;i++){ for(var i=0;i<gcode.length;i++){
// for(var len = gcode.length- 1, i=0;i!=len;i++){
x=undefined; x=undefined;
y=undefined; y=undefined;
z=undefined; z=undefined;
retract = 0; retract = 0;
var line = gcode[i].line;
var percentage = gcode[i].percentage;
extrude=false; extrude=false;
gcode[i] = gcode[i].split(/[\(;]/)[0]; line = line.split(/[\(;]/)[0];
// prevRetract=0; if(reg.test(line)){
// retract=0; var args = line.split(/\s/);
// if(gcode[i].match(/^(?:G0|G1)\s+/i)){
if(reg.test(gcode[i])){
var args = gcode[i].split(/\s/);
for(j=0;j<args.length;j++){ for(j=0;j<args.length;j++){
// console.log(args);
// if(!args[j])continue;
switch(argChar = args[j].charAt(0).toLowerCase()){ switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x': case 'x':
x=args[j].slice(1); x=args[j].slice(1);
// if(x === prevX){
// x=undefined;
// }
break; break;
case 'y': case 'y':
y=args[j].slice(1); y=args[j].slice(1);
// if(y===prevY){
// y=undefined;
// }
break; break;
case 'z': case 'z':
z=args[j].slice(1); z=args[j].slice(1);
z = Number(z); z = Number(z);
if(z == prevZ)continue; if(z == prevZ) continue;
// z = Number(z);
if(z_heights.hasOwnProperty(z)){ if(z_heights.hasOwnProperty(z)){
layer = z_heights[z]; layer = z_heights[z];
}else{ }else{
@ -267,9 +256,6 @@
} }
sendLayer = layer; sendLayer = layer;
sendLayerZ = z; sendLayerZ = z;
// if(parseFloat(prevZ) < )
// if(args[j].charAt(1) === "-")layer--;
// else layer++;
prevZ = z; prevZ = z;
break; break;
case 'e': case 'e':
@ -292,13 +278,11 @@
retract = -1; retract = -1;
} }
else if(prev_extrude["abs"]==0){ else if(prev_extrude["abs"]==0){
// if(prevRetract <0 )prevRetract=retract;
retract = 0; retract = 0;
}else if(prev_extrude["abs"]>0&&prevRetract < 0){ }else if(prev_extrude["abs"]>0&&prevRetract < 0){
prevRetract = 0; prevRetract = 0;
retract = 1; retract = 1;
} else { } else {
// prevRetract = retract;
retract = 0; retract = 0;
} }
prev_extrude[argChar] = numSlice; prev_extrude[argChar] = numSlice;
@ -317,24 +301,24 @@
prev_extrude["abs"] = Math.sqrt((prevX-x)*(prevX-x)+(prevY-y)*(prevY-y)); prev_extrude["abs"] = Math.sqrt((prevX-x)*(prevX-x)+(prevY-y)*(prevY-y));
} }
if(!model[layer])model[layer]=[]; if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i)}; if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i), percentage: percentage};
//{x: x, y: y, z: z, extrude: extrude, retract: retract, noMove: false, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: i}; //{x: x, y: y, z: z, extrude: extrude, retract: retract, noMove: false, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: i};
if(typeof(x) !== 'undefined') prevX = x; if(typeof(x) !== 'undefined') prevX = x;
if(typeof(y) !== 'undefined') prevY = y; if(typeof(y) !== 'undefined') prevY = y;
} else if(gcode[i].match(/^(?:M82)/i)){ } else if(line.match(/^(?:M82)/i)){
extrudeRelative = false; extrudeRelative = false;
}else if(gcode[i].match(/^(?:G91)/i)){ }else if(line.match(/^(?:G91)/i)){
extrudeRelative=true; extrudeRelative=true;
}else if(gcode[i].match(/^(?:G90)/i)){ }else if(line.match(/^(?:G90)/i)){
extrudeRelative=false; extrudeRelative=false;
}else if(gcode[i].match(/^(?:M83)/i)){ }else if(line.match(/^(?:M83)/i)){
extrudeRelative=true; extrudeRelative=true;
}else if(gcode[i].match(/^(?:M101)/i)){ }else if(line.match(/^(?:M101)/i)){
dcExtrude=true; dcExtrude=true;
}else if(gcode[i].match(/^(?:M103)/i)){ }else if(line.match(/^(?:M103)/i)){
dcExtrude=false; dcExtrude=false;
}else if(gcode[i].match(/^(?:G92)/i)){ }else if(line.match(/^(?:G92)/i)){
var args = gcode[i].split(/\s/); var args = line.split(/\s/);
for(j=0;j<args.length;j++){ for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){ switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x': case 'x':
@ -354,16 +338,15 @@
else { else {
prev_extrude[argChar] = numSlice; prev_extrude[argChar] = numSlice;
} }
// prevZ = z;
break; break;
default: default:
break; break;
} }
} }
if(!model[layer])model[layer]=[]; if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: parseFloat(x), y: parseFloat(y), z: parseFloat(z), extrude: extrude, retract: parseFloat(retract), noMove: true, extrusion: (extrude||retract)?parseFloat(prev_extrude["abs"]):0, prevX: parseFloat(prevX), prevY: parseFloat(prevY), prevZ: parseFloat(prevZ), speed: parseFloat(lastF),gcodeLine: parseFloat(i)}; if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: parseFloat(x), y: parseFloat(y), z: parseFloat(z), extrude: extrude, retract: parseFloat(retract), noMove: true, extrusion: (extrude||retract)?parseFloat(prev_extrude["abs"]):0, prevX: parseFloat(prevX), prevY: parseFloat(prevY), prevZ: parseFloat(prevZ), speed: parseFloat(lastF),gcodeLine: parseFloat(i), percentage: percentage};
}else if(gcode[i].match(/^(?:G28)/i)){ }else if(line.match(/^(?:G28)/i)){
var args = gcode[i].split(/\s/); var args = line.split(/\s/);
for(j=0;j<args.length;j++){ for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){ switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x': case 'x':
@ -405,17 +388,11 @@
} }
prevZ = z; prevZ = z;
} }
// x=0, y=0,z=0,prevZ=0, extrude=false;
// if(typeof(prevX) === 'undefined'){prevX=0;}
// if(typeof(prevY) === 'undefined'){prevY=0;}
if(!model[layer])model[layer]=[]; if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i)}; if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i), percentage: percentage};
// if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: x, y: y, z: z, extrude: extrude, retract: retract, noMove:false, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: parseFloat(i)};
} }
if(typeof(sendLayer) !== "undefined"){ if(typeof(sendLayer) !== "undefined"){
// sendLayerToParent(sendLayer, sendLayerZ, i/gcode.length*100);
// sendLayer = undefined;
if(i-lastSend > gcode.length*0.02 && sendMultiLayer.length != 0){ if(i-lastSend > gcode.length*0.02 && sendMultiLayer.length != 0){
lastSend = i; lastSend = i;
@ -429,13 +406,7 @@
sendLayerZ = undefined; sendLayerZ = undefined;
} }
} }
// sendMultiLayer[sendMultiLayer.length] = layer;
// sendMultiLayerZ[sendMultiLayerZ.length] = z;
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100); sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100);
// if(gCodeOptions["sortLayers"])sortLayers();
// if(gCodeOptions["purgeEmptyLayers"])purgeLayers();
}; };

View File

@ -23,57 +23,73 @@ GCODE.gCodeReader = (function(){
purgeEmptyLayers: true, purgeEmptyLayers: true,
analyzeModel: false analyzeModel: false
}; };
var linesCmdIndex = {};
var prepareGCode = function(){ var percentageTree = undefined;
var prepareGCode = function(totalSize){
if(!lines)return; if(!lines)return;
gcode = []; gcode = [];
var i, tmp; var i, tmp, byteCount;
byteCount = 0;
for(i=0;i<lines.length;i++){ for(i=0;i<lines.length;i++){
// if(lines[i].match(/^(G0|G1|G90|G91|G92|M82|M83|G28)/i))gcode.push(lines[i]); byteCount += lines[i].length + 1; // line length + \n
tmp = lines[i].indexOf(";"); tmp = lines[i].indexOf(";");
if(tmp > 1 || tmp === -1) { if(tmp > 1 || tmp === -1) {
gcode.push(lines[i]); gcode.push({line: lines[i], percentage: byteCount * 100 / totalSize});
} }
} }
lines = []; lines = [];
// console.log("GCode prepared");
}; };
var sortLayers = function(){ var sortLayers = function(){
var sortedZ = []; var sortedZ = [];
var tmpModel = []; var tmpModel = [];
// var cnt = 0;
// console.log(z_heights);
for(var layer in z_heights){ for(var layer in z_heights){
sortedZ[z_heights[layer]] = layer; sortedZ[z_heights[layer]] = layer;
// cnt++;
} }
// console.log("cnt is " + cnt);
sortedZ.sort(function(a,b){ sortedZ.sort(function(a,b){
return a-b; return a-b;
}); });
// console.log(sortedZ);
// console.log(model.length);
for(var i=0;i<sortedZ.length;i++){ for(var i=0;i<sortedZ.length;i++){
// console.log("i is " + i +" and sortedZ[i] is " + sortedZ[i] + "and z_heights[] is " + z_heights[sortedZ[i]] );
if(typeof(z_heights[sortedZ[i]]) === 'undefined')continue; if(typeof(z_heights[sortedZ[i]]) === 'undefined')continue;
tmpModel[i] = model[z_heights[sortedZ[i]]]; tmpModel[i] = model[z_heights[sortedZ[i]]];
} }
model = tmpModel; model = tmpModel;
// console.log(model.length);
delete tmpModel; delete tmpModel;
}; };
var prepareLinesIndex = function(){ var prepareLinesIndex = function(){
linesCmdIndex = {}; percentageTree = undefined;
for (var l in model){ for (var l in model) {
for (var i=0; i< model[l].length; i++){ for (var i=0; i< model[l].length; i++) {
linesCmdIndex[model[l][i].gcodeLine] = {layer: l, cmd: i}; var percentage = model[l][i].percentage;
var value = {layer: l, cmd: i};
if (!percentageTree) {
percentageTree = new AVLTree({key: percentage, value: value}, "key");
} else {
percentageTree.add({key: percentage, value: value});
} }
} }
} }
};
var searchInPercentageTree = function(key) {
if (percentageTree === undefined) {
return undefined;
}
var elements = percentageTree.findBest(key);
if (elements.length == 0) {
return undefined;
}
return elements[0];
};
var purgeLayers = function(){ var purgeLayers = function(){
var purge=true; var purge=true;
@ -102,13 +118,13 @@ GCODE.gCodeReader = (function(){
return { return {
loadFile: function(reader){ loadFile: function(reader){
// console.log("loadFile");
model = []; model = [];
z_heights = []; z_heights = [];
var totalSize = reader.target.result.length;
lines = reader.target.result.split(/\n/); lines = reader.target.result.split(/\n/);
reader.target.result = null; reader.target.result = null;
prepareGCode(); prepareGCode(totalSize);
worker.postMessage({ worker.postMessage({
"cmd":"parseGCode", "cmd":"parseGCode",
@ -129,32 +145,21 @@ GCODE.gCodeReader = (function(){
} }
}, },
passDataToRenderer: function(){ passDataToRenderer: function(){
// console.log(model);
if(gCodeOptions["sortLayers"])sortLayers(); if(gCodeOptions["sortLayers"])sortLayers();
// console.log(model);
if(gCodeOptions["purgeEmptyLayers"])purgeLayers(); if(gCodeOptions["purgeEmptyLayers"])purgeLayers();
prepareLinesIndex(); prepareLinesIndex();
// console.log(model);
GCODE.renderer.doRender(model, 0); GCODE.renderer.doRender(model, 0);
// GCODE.renderer3d.setModel(model);
}, },
processLayerFromWorker: function(msg){ processLayerFromWorker: function(msg){
// var cmds = msg.cmds;
// var layerNum = msg.layerNum;
// var zHeightObject = msg.zHeightObject;
// var isEmpty = msg.isEmpty;
// console.log(zHeightObject);
model[msg.layerNum] = msg.cmds; model[msg.layerNum] = msg.cmds;
z_heights[msg.zHeightObject.zValue] = msg.zHeightObject.layer; z_heights[msg.zHeightObject.zValue] = msg.zHeightObject.layer;
// GCODE.renderer.doRender(model, msg.layerNum);
}, },
processMultiLayerFromWorker: function(msg){ processMultiLayerFromWorker: function(msg){
for(var i=0;i<msg.layerNum.length;i++){ for(var i=0;i<msg.layerNum.length;i++){
model[msg.layerNum[i]] = msg.model[msg.layerNum[i]]; model[msg.layerNum[i]] = msg.model[msg.layerNum[i]];
z_heights[msg.zHeightObject.zValue[i]] = msg.layerNum[i]; z_heights[msg.zHeightObject.zValue[i]] = msg.layerNum[i];
} }
// console.log(model);
}, },
processAnalyzeModelDone: function(msg){ processAnalyzeModelDone: function(msg){
min = msg.min; min = msg.min;
@ -190,8 +195,13 @@ GCODE.gCodeReader = (function(){
var result = {first: model[layer][fromSegments].gcodeLine, last: model[layer][toSegments].gcodeLine}; var result = {first: model[layer][fromSegments].gcodeLine, last: model[layer][toSegments].gcodeLine};
return result; return result;
}, },
getLinesCmdIndex: function(line){ getCmdIndexForPercentage: function(percentage) {
return linesCmdIndex[line]; var command = searchInPercentageTree(percentage);
if (command === undefined) {
return undefined
} else {
return command.value;
}
} }
} }
}()); }());

View File

@ -0,0 +1,169 @@
// AVLTree ///////////////////////////////////////////////////////////////////
// self file is originally from the Concentré XML project (version 0.2.1)
// Licensed under GPL and LGPL
//
// Modified by Jeremy Stephens.
//
// Taken from: https://gist.github.com/viking/2424106, modified to not only use string literals when searching
// Pass in the attribute you want to use for comparing
function AVLTree(n, attr) {
var self = this;
self.attr = attr;
self.left = null;
self.right = null;
self.node = n;
self.depth = 1;
self.elements = [n];
self.balance = function() {
var ldepth = self.left == null ? 0 : self.left.depth;
var rdepth = self.right == null ? 0 : self.right.depth;
if (ldepth > rdepth + 1) {
// LR or LL rotation
var lldepth = self.left.left == null ? 0 : self.left.left.depth;
var lrdepth = self.left.right == null ? 0 : self.left.right.depth;
if (lldepth < lrdepth) {
// LR rotation consists of a RR rotation of the left child
self.left.rotateRR();
// plus a LL rotation of self node, which happens anyway
}
self.rotateLL();
} else if (ldepth + 1 < rdepth) {
// RR or RL rorarion
var rrdepth = self.right.right == null ? 0 : self.right.right.depth;
var rldepth = self.right.left == null ? 0 : self.right.left.depth;
if (rldepth > rrdepth) {
// RR rotation consists of a LL rotation of the right child
self.right.rotateLL();
// plus a RR rotation of self node, which happens anyway
}
self.rotateRR();
}
}
self.rotateLL = function() {
// the left side is too long => rotate from the left (_not_ leftwards)
var nodeBefore = self.node;
var elementsBefore = self.elements;
var rightBefore = self.right;
self.node = self.left.node;
self.elements = self.left.elements;
self.right = self.left;
self.left = self.left.left;
self.right.left = self.right.right;
self.right.right = rightBefore;
self.right.node = nodeBefore;
self.right.elements = elementsBefore;
self.right.updateInNewLocation();
self.updateInNewLocation();
}
self.rotateRR = function() {
// the right side is too long => rotate from the right (_not_ rightwards)
var nodeBefore = self.node;
var elementsBefore = self.elements;
var leftBefore = self.left;
self.node = self.right.node;
self.elements = self.right.elements;
self.left = self.right;
self.right = self.right.right;
self.left.right = self.left.left;
self.left.left = leftBefore;
self.left.node = nodeBefore;
self.left.elements = elementsBefore;
self.left.updateInNewLocation();
self.updateInNewLocation();
}
self.updateInNewLocation = function() {
self.getDepthFromChildren();
}
self.getDepthFromChildren = function() {
self.depth = self.node == null ? 0 : 1;
if (self.left != null) {
self.depth = self.left.depth + 1;
}
if (self.right != null && self.depth <= self.right.depth) {
self.depth = self.right.depth + 1;
}
}
self.compare = function(n1, n2) {
var v1 = n1[self.attr];
var v2 = n2[self.attr];
if (v1 == v2) {
return 0;
}
if (v1 < v2) {
return -1;
}
return 1;
}
self.add = function(n) {
var o = self.compare(n, self.node);
if (o == 0) {
self.elements.push(n);
return false;
}
var ret = false;
if (o == -1) {
if (self.left == null) {
self.left = new AVLTree(n, self.attr);
ret = true;
} else {
ret = self.left.add(n);
if (ret) {
self.balance();
}
}
} else if (o == 1) {
if (self.right == null) {
self.right = new AVLTree(n, self.attr);
ret = true;
} else {
ret = self.right.add(n);
if (ret) {
self.balance();
}
}
}
if (ret) {
self.getDepthFromChildren();
}
return ret;
}
self.findBest = function(value) {
if (value < self.node[self.attr]) {
if (self.left != null) {
return self.left.findBest(value);
}
} else if (value > self.node[self.attr]) {
if (self.right != null) {
return self.right.findBest(value);
}
}
return self.elements;
}
self.find = function(value) {
var elements = self.findBest(value);
for (var i = 0; i < elements.length; i++) {
if (elements[i][self.attr] == value) {
return elements;
}
}
return false;
}
}

View File

@ -234,7 +234,11 @@ function PrinterStateViewModel(loginStateViewModel) {
var filepos = self.filepos() ? self.filepos() : "-"; var filepos = self.filepos() ? self.filepos() : "-";
return filepos + " / " + self.filesize(); return filepos + " / " + self.filesize();
}); });
self.heightString = ko.computed(function() {
if (!self.currentHeight())
return "-";
return self.currentHeight();
})
self.progressString = ko.computed(function() { self.progressString = ko.computed(function() {
if (!self.progress()) if (!self.progress())
return 0; return 0;
@ -1077,14 +1081,17 @@ function GcodeViewModel(loginStateViewModel) {
} }
self._processData = function(data) { self._processData = function(data) {
if(!self.enabled)return; if (!self.enabled) return;
if (!data.job.filename) return;
if(self.loadedFilename == data.job.filename) { if(self.loadedFilename && self.loadedFilename == data.job.filename) {
var cmdIndex = GCODE.gCodeReader.getLinesCmdIndex(data.progress.progress); if (data.state.flags && (data.state.flags.printing || data.state.flags.paused)) {
var cmdIndex = GCODE.gCodeReader.getCmdIndexForPercentage(data.progress.progress * 100);
if(cmdIndex){ if(cmdIndex){
GCODE.renderer.render(cmdIndex.layer, 0, cmdIndex.cmd); GCODE.renderer.render(cmdIndex.layer, 0, cmdIndex.cmd);
GCODE.ui.updateLayerInfo(cmdIndex.layer); GCODE.ui.updateLayerInfo(cmdIndex.layer);
} }
}
self.errorCount = 0 self.errorCount = 0
} else if (data.job.filename) { } else if (data.job.filename) {
self.loadFile(data.job.filename); self.loadFile(data.job.filename);
@ -1729,43 +1736,48 @@ function ItemListHelper(listType, supportedSorting, supportedFilters, defaultSor
//~~ local storage //~~ local storage
self._saveCurrentSortingToLocalStorage = function() { self._saveCurrentSortingToLocalStorage = function() {
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() {
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() {
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() {
self._initializeLocalStorage(); if ( self._initializeLocalStorage() ) {
self.currentFilters(_.intersection(_.keys(self.supportedFilters), JSON.parse(localStorage[self.listType + "." + "currentFilters"]))); self.currentFilters(_.intersection(_.keys(self.supportedFilters), JSON.parse(localStorage[self.listType + "." + "currentFilters"])));
} }
}
self._initializeLocalStorage = function() { self._initializeLocalStorage = function() {
if (!Modernizr.localstorage)
return false;
if (localStorage[self.listType + "." + "currentSorting"] !== undefined && localStorage[self.listType + "." + "currentFilters"] !== undefined && JSON.parse(localStorage[self.listType + "." + "currentFilters"]) instanceof Array) if (localStorage[self.listType + "." + "currentSorting"] !== undefined && localStorage[self.listType + "." + "currentFilters"] !== undefined && JSON.parse(localStorage[self.listType + "." + "currentFilters"]) instanceof Array)
return; return true;
localStorage[self.listType + "." + "currentSorting"] = self.defaultSorting; localStorage[self.listType + "." + "currentSorting"] = self.defaultSorting;
localStorage[self.listType + "." + "currentFilters"] = JSON.stringify(self.defaultFilters); localStorage[self.listType + "." + "currentFilters"] = JSON.stringify(self.defaultFilters);
return true;
} }
self._loadCurrentFiltersFromLocalStorage(); self._loadCurrentFiltersFromLocalStorage();

View File

@ -111,7 +111,7 @@
File: <strong data-bind="text: filename"></strong>&nbsp;<strong data-bind="visible: sd">(SD)</strong><br> File: <strong data-bind="text: filename"></strong>&nbsp;<strong data-bind="visible: sd">(SD)</strong><br>
Filament: <strong data-bind="text: filament"></strong><br> Filament: <strong data-bind="text: filament"></strong><br>
Estimated Print Time: <strong data-bind="text: estimatedPrintTime"></strong><br> Estimated Print Time: <strong data-bind="text: estimatedPrintTime"></strong><br>
Height: <strong data-bind="text: currentHeight"></strong><br> Height: <strong data-bind="text: heightString"></strong><br>
Print Time: <strong data-bind="text: printTime"></strong><br> Print Time: <strong data-bind="text: printTime"></strong><br>
Print Time Left: <strong data-bind="text: printTimeLeft"></strong><br> Print Time Left: <strong data-bind="text: printTimeLeft"></strong><br>
Printed: <strong data-bind="text: byteString"></strong><br> Printed: <strong data-bind="text: byteString"></strong><br>
@ -579,6 +579,7 @@
<script type="text/javascript" src="{{ url_for('static', filename='js/modernizr.custom.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/modernizr.custom.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/underscore.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/underscore.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/knockout.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/knockout.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/avltree.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap/bootstrap.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap/bootstrap.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap/bootstrap-modalmanager.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap/bootstrap-modalmanager.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap/bootstrap-modal.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap/bootstrap-modal.js') }}"></script>

View File

@ -2,6 +2,8 @@
__author__ = "Gina Häußge <osd@foosel.net>" __author__ = "Gina Häußge <osd@foosel.net>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
import re
def getFormattedSize(num): def getFormattedSize(num):
""" """
Taken from http://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size Taken from http://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
@ -39,3 +41,6 @@ def getClass(name):
for comp in parts[1:]: for comp in parts[1:]:
m = getattr(m, comp) m = getattr(m, comp)
return m return m
def matchesGcode(line, gcode):
return re.search("^\s*%s\D" % gcode, line, re.I)

View File

@ -16,6 +16,8 @@ import serial
from octoprint.util.avr_isp import stk500v2 from octoprint.util.avr_isp import stk500v2
from octoprint.util.avr_isp import ispBase from octoprint.util.avr_isp import ispBase
from octoprint.util import matchesGcode
from octoprint.settings import settings from octoprint.settings import settings
try: try:
@ -358,7 +360,7 @@ class MachineCom(object):
self._bedTargetTemp = 0 self._bedTargetTemp = 0
self._commandQueue = queue.Queue() self._commandQueue = queue.Queue()
self._logQueue = queue.Queue(256) self._logQueue = queue.Queue(256)
self._currentZ = -1 self._currentZ = None
self._heatupWaitStartTime = 0 self._heatupWaitStartTime = 0
self._heatupWaitTimeLost = 0.0 self._heatupWaitTimeLost = 0.0
@ -846,20 +848,20 @@ class MachineCom(object):
with self._sendingLock: with self._sendingLock:
if self._serial is None: if self._serial is None:
return return
if 'M109' in cmd or 'M190' in cmd: if matchesGcode(cmd, "M109") or matchesGcode(cmd, "M190"):
self._heatupWaitStartTime = time.time() self._heatupWaitStartTime = time.time()
if 'M104' in cmd or 'M109' in cmd: if matchesGcode(cmd, "M104") or matchesGcode(cmd, "M109"):
try: try:
self._targetTemp = float(re.search('S([0-9]+)', cmd).group(1)) self._targetTemp = float(re.search('S([0-9]+)', cmd).group(1))
except: except:
pass pass
if 'M140' in cmd or 'M190' in cmd: if matchesGcode(cmd, "M140") or matchesGcode(cmd, "M190"):
try: try:
self._bedTargetTemp = float(re.search('S([0-9]+)', cmd).group(1)) self._bedTargetTemp = float(re.search('S([0-9]+)', cmd).group(1))
except: except:
pass pass
if "M110" in cmd: if matchesGcode(cmd, "M110"):
newLineNumber = None newLineNumber = None
if " N" in cmd: if " N" in cmd:
try: try:
@ -946,10 +948,12 @@ class MachineCom(object):
if not self.isStreaming(): if not self.isStreaming():
try: try:
if line == 'M0' or line == 'M1': if matchesGcode(line, "M0") or matchesGcode(line, "M1"):
self.setPause(True) self.setPause(True)
line = 'M105' #Don't send the M0 or M1 to the machine, as M0 and M1 are handled as an LCD menu pause. line = "M105" # Don't send the M0 or M1 to the machine, as M0 and M1 are handled as an LCD menu pause.
if ('G0' in line or 'G1' in line) and 'Z' in line: if self._printSection in self._feedRateModifier:
line = re.sub('F([0-9]*)', lambda m: 'F' + str(int(int(m.group(1)) * self._feedRateModifier[self._printSection])), line)
if (matchesGcode(line, "G0") or matchesGcode(line, "G1")) and 'Z' in line:
z = float(re.search('Z([0-9\.]*)', line).group(1)) z = float(re.search('Z([0-9\.]*)', line).group(1))
if self._currentZ != z: if self._currentZ != z:
self._currentZ = z self._currentZ = z