parent
cd04fb705f
commit
5008502e13
|
@ -546,6 +546,11 @@ class MachineCom(object):
|
|||
def setFeedrateModifier(self, type, value):
|
||||
self._feedRateModifier[type] = value
|
||||
|
||||
def getFeedrateModifiers(self):
|
||||
result = {}
|
||||
result.update(self._feedRateModifier)
|
||||
return result
|
||||
|
||||
def getExceptionString():
|
||||
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])
|
||||
|
|
|
@ -50,6 +50,7 @@ def printerState():
|
|||
bedTargetTemp = printer.currentBedTargetTemp
|
||||
jobData = printer.jobData()
|
||||
gcodeState = printer.gcodeState()
|
||||
feedrateState = printer.feedrateState()
|
||||
|
||||
result = {
|
||||
"state": printer.getStateString(),
|
||||
|
@ -74,6 +75,9 @@ def printerState():
|
|||
gcodeState["filename"] = gcodeState["filename"].replace(UPLOAD_FOLDER + os.sep, "")
|
||||
result["gcode"] = gcodeState
|
||||
|
||||
if feedrateState is not None:
|
||||
result["feedrate"] = feedrateState
|
||||
|
||||
if request.values.has_key("temperatures"):
|
||||
result["temperatures"] = printer.temps
|
||||
|
||||
|
@ -184,6 +188,18 @@ def jog():
|
|||
|
||||
return jsonify(SUCCESS)
|
||||
|
||||
@app.route(BASEURL + "control/speed", methods=["POST"])
|
||||
def speed():
|
||||
if not printer.isOperational():
|
||||
return jsonify(SUCCESS)
|
||||
|
||||
for key in ["outerWall", "innerWall", "fill", "support"]:
|
||||
if request.values.has_key(key):
|
||||
value = int(request.values[key])
|
||||
printer.setFeedrateModifier(key, value)
|
||||
|
||||
return jsonify(feedrate = printer.feedrateState())
|
||||
|
||||
#~~ GCODE file handling
|
||||
|
||||
@app.route(BASEURL + "gcodefiles", methods=["GET"])
|
||||
|
@ -194,7 +210,7 @@ def readGcodeFiles():
|
|||
continue
|
||||
files.append({
|
||||
"name": osFile,
|
||||
"size": sizeof_fmt(os.stat(UPLOAD_FOLDER + os.sep + osFile).st_size)
|
||||
"size": sizeof_fmt(os.stat(os.path.join(UPLOAD_FOLDER, osFile)).st_size)
|
||||
})
|
||||
return jsonify(files=files)
|
||||
|
||||
|
@ -210,7 +226,7 @@ def uploadGcodeFile():
|
|||
@app.route(BASEURL + "gcodefiles/load", methods=["POST"])
|
||||
def loadGcodeFile():
|
||||
filename = request.values["filename"]
|
||||
printer.loadGcode(UPLOAD_FOLDER + os.sep + filename)
|
||||
printer.loadGcode(os.path.join(UPLOAD_FOLDER, filename))
|
||||
return jsonify(SUCCESS)
|
||||
|
||||
@app.route(BASEURL + "gcodefiles/delete", methods=["POST"])
|
||||
|
@ -218,7 +234,7 @@ def deleteGcodeFile():
|
|||
if request.values.has_key("filename"):
|
||||
filename = request.values["filename"]
|
||||
if allowed_file(filename):
|
||||
secure = UPLOAD_FOLDER + os.sep + secure_filename(filename)
|
||||
secure = os.path.join(UPLOAD_FOLDER, secure_filename(filename))
|
||||
if os.path.exists(secure):
|
||||
os.remove(secure)
|
||||
return readGcodeFiles()
|
||||
|
|
|
@ -14,7 +14,7 @@ def getConnectionOptions():
|
|||
Retrieves the available ports, baudrates, prefered port and baudrate for connecting to the printer.
|
||||
"""
|
||||
return {
|
||||
"ports": sorted(machineCom.serialList(), key=str.lower),
|
||||
"ports": machineCom.serialList(),
|
||||
"baudrates": sorted(machineCom.baudrateList(), key=int, reverse=True),
|
||||
"portPreference": profile.getPreference('serial_port_auto'),
|
||||
"baudratePreference": int(profile.getPreference('serial_baud_auto'))
|
||||
|
@ -47,6 +47,8 @@ class Printer():
|
|||
|
||||
self.gcodeLoader = None
|
||||
|
||||
self.feedrateModifierMapping = {"outerWall": "WALL-OUTER", "innerWall": "WALL_INNER", "fill": "FILL", "support": "SUPPORT"}
|
||||
|
||||
# comm
|
||||
self.comm = None
|
||||
|
||||
|
@ -80,6 +82,12 @@ class Printer():
|
|||
for command in commands:
|
||||
self.comm.sendCommand(command)
|
||||
|
||||
def setFeedrateModifier(self, structure, percentage):
|
||||
if (not self.feedrateModifierMapping.has_key(structure)) or percentage < 0:
|
||||
return
|
||||
|
||||
self.comm.setFeedrateModifier(self.feedrateModifierMapping[structure], percentage / 100.0)
|
||||
|
||||
def mcLog(self, message):
|
||||
"""
|
||||
Callback method for the comm object, called upon log output.
|
||||
|
@ -200,6 +208,19 @@ class Printer():
|
|||
else:
|
||||
return None
|
||||
|
||||
def feedrateState(self):
|
||||
if self.comm is not None:
|
||||
feedrateModifiers = self.comm.getFeedrateModifiers()
|
||||
result = {}
|
||||
for structure in self.feedrateModifierMapping.keys():
|
||||
if (feedrateModifiers.has_key(self.feedrateModifierMapping[structure])):
|
||||
result[structure] = int(round(feedrateModifiers[self.feedrateModifierMapping[structure]] * 100))
|
||||
else:
|
||||
result[structure] = 100
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def getStateString(self):
|
||||
"""
|
||||
Returns a human readable string corresponding to the current communication state.
|
||||
|
|
|
@ -48,10 +48,11 @@ table th.gcode_files_action, table td.gcode_files_action {
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
#temp_newTemp {
|
||||
#temp_newTemp, #temp_newBedTemp, #speed_innerWall, #speed_outerWall, #speed_fill, #speed_support {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
#connection_ports, #connection_baudrates {
|
||||
width: 100%;
|
||||
}
|
|
@ -228,6 +228,46 @@ function TemperatureViewModel() {
|
|||
}
|
||||
var temperatureViewModel = new TemperatureViewModel();
|
||||
|
||||
function SpeedViewModel() {
|
||||
var self = this;
|
||||
|
||||
self.outerWall = ko.observable(undefined);
|
||||
self.innerWall = ko.observable(undefined);
|
||||
self.fill = ko.observable(undefined);
|
||||
self.support = ko.observable(undefined);
|
||||
|
||||
self.isErrorOrClosed = ko.observable(undefined);
|
||||
self.isOperational = ko.observable(undefined);
|
||||
self.isPrinting = ko.observable(undefined);
|
||||
self.isPaused = ko.observable(undefined);
|
||||
self.isError = ko.observable(undefined);
|
||||
self.isReady = ko.observable(undefined);
|
||||
self.isLoading = ko.observable(undefined);
|
||||
|
||||
self.fromResponse = function(response) {
|
||||
self.isErrorOrClosed(response.closedOrError);
|
||||
self.isOperational(response.operational);
|
||||
self.isPaused(response.paused);
|
||||
self.isPrinting(response.printing);
|
||||
self.isError(response.error);
|
||||
self.isReady(response.ready);
|
||||
self.isLoading(response.loading);
|
||||
|
||||
if (response.feedrate) {
|
||||
self.outerWall(response.feedrate.outerWall);
|
||||
self.innerWall(response.feedrate.innerWall);
|
||||
self.fill(response.feedrate.fill);
|
||||
self.support(response.feedrate.support);
|
||||
} else {
|
||||
self.outerWall(undefined);
|
||||
self.innerWall(undefined);
|
||||
self.fill(undefined);
|
||||
self.support(undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
var speedViewModel = new SpeedViewModel();
|
||||
|
||||
function TerminalViewModel() {
|
||||
var self = this;
|
||||
|
||||
|
@ -293,7 +333,7 @@ function GcodeFilesViewModel() {
|
|||
}
|
||||
var gcodeFilesViewModel = new GcodeFilesViewModel();
|
||||
|
||||
function DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, terminalViewModel) {
|
||||
function DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, speedViewModel, terminalViewModel) {
|
||||
var self = this;
|
||||
|
||||
self.updateInterval = 500;
|
||||
|
@ -304,6 +344,7 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView
|
|||
self.printerStateViewModel = printerStateViewModel;
|
||||
self.temperatureViewModel = temperatureViewModel;
|
||||
self.terminalViewModel = terminalViewModel;
|
||||
self.speedViewModel = speedViewModel;
|
||||
|
||||
self.requestData = function() {
|
||||
var parameters = {};
|
||||
|
@ -321,6 +362,7 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView
|
|||
success: function(response) {
|
||||
self.printerStateViewModel.fromResponse(response);
|
||||
self.connectionViewModel.fromStateResponse(response);
|
||||
self.speedViewModel.fromResponse(response);
|
||||
|
||||
if (response.temperatures)
|
||||
self.temperatureViewModel.fromResponse(response);
|
||||
|
@ -336,9 +378,12 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView
|
|||
setTimeout(self.requestData, self.updateInterval);
|
||||
}
|
||||
}
|
||||
var dataUpdater = new DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, terminalViewModel);
|
||||
var dataUpdater = new DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, speedViewModel, terminalViewModel);
|
||||
|
||||
$(function() {
|
||||
|
||||
//~~ Print job control
|
||||
|
||||
$("#job_print").click(function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/print",
|
||||
|
@ -363,6 +408,8 @@ $(function() {
|
|||
})
|
||||
})
|
||||
|
||||
//~~ Temperature control
|
||||
|
||||
$("#temp_newTemp_set").click(function() {
|
||||
var newTemp = $("#temp_newTemp").val();
|
||||
$.ajax({
|
||||
|
@ -384,6 +431,8 @@ $(function() {
|
|||
})
|
||||
})
|
||||
|
||||
//~~ Jog controls
|
||||
|
||||
function jogCommand(axis, distance) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/jog",
|
||||
|
@ -409,16 +458,44 @@ $(function() {
|
|||
$("#jog_xy_home").click(function() {homeCommand("XY")});
|
||||
$("#jog_z_home").click(function() {homeCommand("Z")});
|
||||
|
||||
//~~ Speed controls
|
||||
|
||||
function speedCommand(structure) {
|
||||
var speedSetting = $("#speed_" + structure).val();
|
||||
if (speedSetting) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/speed",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: structure + "=" + speedSetting,
|
||||
success: function(response) {
|
||||
$("#speed_" + structure).val("")
|
||||
speedViewModel.fromResponse(response);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
$("#speed_outerWall_set").click(function() {speedCommand("outerWall")});
|
||||
$("#speed_innerWall_set").click(function() {speedCommand("innerWall")});
|
||||
$("#speed_support_set").click(function() {speedCommand("support")});
|
||||
$("#speed_fill_set").click(function() {speedCommand("fill")});
|
||||
|
||||
//~~ Terminal
|
||||
|
||||
$("#terminal-send").click(function () {
|
||||
var command = $("#terminal-command").val();
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/command",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: "command=" + command
|
||||
})
|
||||
if (command) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/command",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: "command=" + command
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
//~~ Gcode upload
|
||||
|
||||
$("#gcode_upload").fileupload({
|
||||
dataType: "json",
|
||||
done: function (e, data) {
|
||||
|
@ -430,12 +507,17 @@ $(function() {
|
|||
}
|
||||
});
|
||||
|
||||
//~~ knockout.js bindings
|
||||
|
||||
ko.applyBindings(connectionViewModel, document.getElementById("connection"));
|
||||
ko.applyBindings(printerStateViewModel, document.getElementById("state"));
|
||||
ko.applyBindings(gcodeFilesViewModel, document.getElementById("files"));
|
||||
ko.applyBindings(temperatureViewModel, document.getElementById("temp"));
|
||||
ko.applyBindings(printerStateViewModel, document.getElementById("jog"));
|
||||
ko.applyBindings(terminalViewModel, document.getElementById("term"));
|
||||
ko.applyBindings(speedViewModel, document.getElementById("speed"));
|
||||
|
||||
//~~ startup commands
|
||||
|
||||
dataUpdater.requestData();
|
||||
$.ajax({
|
||||
|
|
|
@ -175,7 +175,35 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="speed">
|
||||
Here be speed settings
|
||||
<div class="form-horizontal" style="margin-bottom: 20px">
|
||||
<label for="speed_outerWall">Outer Wall</label>
|
||||
<div class="input-append">
|
||||
<input type="text" id="speed_outerWall" class="input-mini" data-bind="enable: isOperational(), attr: {placeholder: outerWall}">
|
||||
<span class="add-on">%</span>
|
||||
<button type="submit" class="btn" id="speed_outerWall_set" data-bind="enable: isOperational()">Set</button>
|
||||
</div>
|
||||
|
||||
<label for="speed_innerWall">Inner Wall</label>
|
||||
<div class="input-append">
|
||||
<input type="text" id="speed_innerWall" class="input-mini" data-bind="enable: isOperational(), attr: {placeholder: innerWall}">
|
||||
<span class="add-on">%</span>
|
||||
<button type="submit" class="btn" id="speed_innerWall_set" data-bind="enable: isOperational()">Set</button>
|
||||
</div>
|
||||
|
||||
<label for="speed_fill">Fill</label>
|
||||
<div class="input-append">
|
||||
<input type="text" id="speed_fill" class="input-mini" data-bind="enable: isOperational(), attr: {placeholder: fill}">
|
||||
<span class="add-on">%</span>
|
||||
<button type="submit" class="btn" id="speed_fill_set" data-bind="enable: isOperational()">Set</button>
|
||||
</div>
|
||||
|
||||
<label for="speed_support">Support</label>
|
||||
<div class="input-append">
|
||||
<input type="text" id="speed_support" class="input-mini" data-bind="enable: isOperational(), attr: {placeholder: support}">
|
||||
<span class="add-on">%</span>
|
||||
<button type="submit" class="btn" id="speed_support_set" data-bind="enable: isOperational()">Set</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="term">
|
||||
<pre id="terminal-output" class="pre-scrollable"></pre>
|
||||
|
|
Loading…
Reference in New Issue