Fully switched to printer profiles
This commit is contained in:
parent
05e54fa0c6
commit
2ea1b9df6c
12 changed files with 114 additions and 192 deletions
|
|
@ -94,7 +94,7 @@ class NoSuchStorage(Exception):
|
|||
|
||||
|
||||
class FileManager(object):
|
||||
def __init__(self, analysis_queue, slicing_manager, initial_storage_managers=None):
|
||||
def __init__(self, analysis_queue, slicing_manager, printer_profile_manager, initial_storage_managers=None):
|
||||
self._logger = logging.getLogger(__name__)
|
||||
self._analysis_queue = analysis_queue
|
||||
self._analysis_queue.register_finish_callback(self._on_analysis_finished)
|
||||
|
|
@ -104,6 +104,7 @@ class FileManager(object):
|
|||
self._storage_managers.update(initial_storage_managers)
|
||||
|
||||
self._slicing_manager = slicing_manager
|
||||
self._printer_profile_manager = printer_profile_manager
|
||||
|
||||
import threading
|
||||
self._slicing_jobs = dict()
|
||||
|
|
@ -123,10 +124,11 @@ class FileManager(object):
|
|||
|
||||
def _determine_analysis_backlog(self, storage_type, storage_manager):
|
||||
self._logger.info("Adding backlog items from {storage_type} to analysis queue".format(**locals()))
|
||||
for entry, path in storage_manager.analysis_backlog:
|
||||
for entry, path, printer_profile in storage_manager.analysis_backlog:
|
||||
file_type = get_file_type(path)[-1]
|
||||
|
||||
queue_entry = QueueEntry(entry, file_type, storage_type, path)
|
||||
# we'll use the default printer profile for the backlog since we don't know better
|
||||
queue_entry = QueueEntry(entry, file_type, storage_type, path, self._printer_profile_manager.get_default())
|
||||
self._analysis_queue.enqueue(queue_entry, high_priority=False)
|
||||
|
||||
def add_storage(self, storage_type, storage_manager):
|
||||
|
|
@ -153,7 +155,7 @@ class FileManager(object):
|
|||
def slice(self, slicer_name, source_location, source_path, dest_location, dest_path, profile=None, printer_profile_id=None, overrides=None, callback=None, callback_args=None):
|
||||
absolute_source_path = self.get_absolute_path(source_location, source_path)
|
||||
|
||||
def stlProcessed(source_location, source_path, tmp_path, dest_location, dest_path, start_time, callback, callback_args, _error=None, _cancelled=False):
|
||||
def stlProcessed(source_location, source_path, tmp_path, dest_location, dest_path, start_time, printer_profile_id, callback, callback_args, _error=None, _cancelled=False):
|
||||
try:
|
||||
if _error:
|
||||
eventManager().fire(Events.SLICING_FAILED, {"stl": source_path, "gcode": dest_path, "reason": _error})
|
||||
|
|
@ -179,7 +181,9 @@ class FileManager(object):
|
|||
links = [("model", dict(name=source_path))]
|
||||
_, stl_name = self.split_path(source_location, source_path)
|
||||
file_obj = Wrapper(stl_name, temp_path, hash)
|
||||
self.add_file(dest_location, dest_path, file_obj, links=links, allow_overwrite=True)
|
||||
|
||||
printer_profile = self._printer_profile_manager.get(printer_profile_id)
|
||||
self.add_file(dest_location, dest_path, file_obj, links=links, allow_overwrite=True, printer_profile=printer_profile)
|
||||
|
||||
end_time = time.time()
|
||||
eventManager().fire(Events.SLICING_DONE, {"stl": source_path, "gcode": dest_path, "time": end_time - start_time})
|
||||
|
|
@ -222,7 +226,7 @@ class FileManager(object):
|
|||
|
||||
self._slicing_jobs[dest_job_key] = self._slicing_jobs[source_job_key] = (slicer_name, absolute_source_path, temp_path)
|
||||
|
||||
args = (source_location, source_path, temp_path, dest_location, dest_path, start_time, callback, callback_args)
|
||||
args = (source_location, source_path, temp_path, dest_location, dest_path, start_time, printer_profile_id, callback, callback_args)
|
||||
return self._slicing_manager.slice(
|
||||
slicer_name,
|
||||
absolute_source_path,
|
||||
|
|
@ -266,13 +270,16 @@ class FileManager(object):
|
|||
result[dst] = self._storage_managers[dst].list_files(path=path, filter=filter, recursive=recursive)
|
||||
return result
|
||||
|
||||
def add_file(self, destination, path, file_object, links=None, allow_overwrite=False):
|
||||
file_path = self._storage(destination).add_file(path, file_object, links=links, allow_overwrite=allow_overwrite)
|
||||
def add_file(self, destination, path, file_object, links=None, allow_overwrite=False, printer_profile=None):
|
||||
if printer_profile is None:
|
||||
printer_profile = self._printer_profile_manager.get_current_or_default()
|
||||
|
||||
file_path = self._storage(destination).add_file(path, file_object, links=links, printer_profile=printer_profile, allow_overwrite=allow_overwrite)
|
||||
absolute_path = self._storage(destination).get_absolute_path(file_path)
|
||||
|
||||
file_type = get_file_type(absolute_path)
|
||||
if file_type:
|
||||
queue_entry = QueueEntry(file_path, file_type[-1], destination, absolute_path)
|
||||
queue_entry = QueueEntry(file_path, file_type[-1], destination, absolute_path, printer_profile)
|
||||
self._analysis_queue.enqueue(queue_entry, high_priority=True)
|
||||
|
||||
eventManager().fire(Events.UPDATED_FILES, dict(type="printables"))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from octoprint.events import Events, eventManager
|
|||
import octoprint.util.gcodeInterpreter as gcodeInterpreter
|
||||
|
||||
|
||||
class QueueEntry(collections.namedtuple("QueueEntry", "path, type, location, absolute_path")):
|
||||
class QueueEntry(collections.namedtuple("QueueEntry", "path, type, location, absolute_path, printer_profile")):
|
||||
def __str__(self):
|
||||
return "{location}:{path}".format(location=self.location, path=self.path)
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ class GcodeAnalysisQueue(AbstractAnalysisQueue):
|
|||
def _do_analysis(self):
|
||||
try:
|
||||
self._gcode = gcodeInterpreter.gcode()
|
||||
self._gcode.load(self._current.absolute_path)
|
||||
self._gcode.load(self._current.absolute_path, self._current.printer_profile)
|
||||
|
||||
result = dict()
|
||||
if self._gcode.totalMoveTimeMinute:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class StorageInterface(object):
|
|||
def remove_folder(self, path, recursive=True):
|
||||
raise NotImplementedError()
|
||||
|
||||
def add_file(self, path, file_object, links=None, allow_overwrite=False):
|
||||
def add_file(self, path, file_object, printer_profile=None, links=None, allow_overwrite=False):
|
||||
raise NotImplementedError()
|
||||
|
||||
def remove_file(self, path):
|
||||
|
|
@ -111,10 +111,16 @@ class LocalFileStorage(StorageInterface):
|
|||
absolute_path = os.path.join(path, entry)
|
||||
if os.path.isfile(absolute_path):
|
||||
if not entry in metadata or not isinstance(metadata[entry], dict) or not "analysis" in metadata[entry]:
|
||||
yield entry, absolute_path
|
||||
printer_profile_rels = self.get_link(absolute_path, "printerprofile")
|
||||
if printer_profile_rels:
|
||||
printer_profile_id = printer_profile_rels[0]["id"]
|
||||
else:
|
||||
printer_profile_id = None
|
||||
|
||||
yield entry, absolute_path, printer_profile_id
|
||||
elif os.path.isdir(absolute_path):
|
||||
for sub_entry in self._analysis_backlog_generator(absolute_path):
|
||||
yield self.join_path(entry, sub_entry), os.path.join(absolute_path, sub_entry)
|
||||
yield self.join_path(entry, sub_entry[0]), sub_entry[1], sub_entry[2]
|
||||
|
||||
def file_exists(self, path):
|
||||
path, name = self.sanitize(path)
|
||||
|
|
@ -221,13 +227,14 @@ class LocalFileStorage(StorageInterface):
|
|||
import shutil
|
||||
shutil.rmtree(folder_path)
|
||||
|
||||
def add_file(self, path, file_object, links=None, allow_overwrite=False):
|
||||
def add_file(self, path, file_object, printer_profile=None, links=None, allow_overwrite=False):
|
||||
"""
|
||||
Adds the file ``file_object`` as ``path``
|
||||
|
||||
:param path: the file's new path, will be sanitized
|
||||
:param file_object: a file object that provides a ``save`` method which will be called with the destination path
|
||||
where the object should then store its contents
|
||||
:param printer_profile: the printer profile associated with this file (if any)
|
||||
:param links: any links to add with the file
|
||||
:param allow_overwrite: if set to True no error will be raised if the file already exists and the existing file
|
||||
and its metadata will just be silently overwritten
|
||||
|
|
@ -266,8 +273,13 @@ class LocalFileStorage(StorageInterface):
|
|||
self._save_metadata(path, metadata)
|
||||
|
||||
# process any links that were also provided for adding to the file
|
||||
if links:
|
||||
self._add_links(name, path, links)
|
||||
if not links:
|
||||
links = []
|
||||
|
||||
if printer_profile is not None:
|
||||
links.append(("printerprofile", dict(id=printer_profile["id"], name=printer_profile["name"])))
|
||||
|
||||
self._add_links(name, path, links)
|
||||
|
||||
return self.rel_path((path, name))
|
||||
|
||||
|
|
@ -322,6 +334,11 @@ class LocalFileStorage(StorageInterface):
|
|||
else:
|
||||
return None
|
||||
|
||||
def get_link(self, path, rel):
|
||||
path, name = self.sanitize(path)
|
||||
return self._get_links(name, path, rel)
|
||||
|
||||
|
||||
def add_link(self, path, rel, data):
|
||||
"""
|
||||
Adds a link of relation ``rel`` to file ``path`` with the given ``data``.
|
||||
|
|
@ -510,6 +527,22 @@ class LocalFileStorage(StorageInterface):
|
|||
except IndexError:
|
||||
pass
|
||||
|
||||
def _get_links(self, name, path, searched_rel):
|
||||
metadata = self._get_metadata(path)
|
||||
result = []
|
||||
|
||||
if not name in metadata:
|
||||
return result
|
||||
|
||||
if not "links" in metadata[name]:
|
||||
return result
|
||||
|
||||
for data in metadata[name]["links"]:
|
||||
if not "rel" in data or not data["rel"] == searched_rel:
|
||||
continue
|
||||
result.append(data)
|
||||
return result
|
||||
|
||||
def _add_links(self, name, path, links):
|
||||
file_type = octoprint.filemanager.get_file_type(name)
|
||||
if file_type:
|
||||
|
|
|
|||
|
|
@ -642,7 +642,7 @@ class Profile(object):
|
|||
return int(value * 1000)
|
||||
|
||||
def get_gcode_template(self, key):
|
||||
extruder_count = s.globalGetInt(["printerParameters", "numExtruders"])
|
||||
extruder_count = self.get_int("extruder_amount")
|
||||
|
||||
if key in self._profile:
|
||||
gcode = self._profile[key]
|
||||
|
|
@ -654,14 +654,6 @@ class Profile(object):
|
|||
else:
|
||||
return gcode
|
||||
|
||||
def get_machine_extruder_offset(self, extruder, axis):
|
||||
extruder_offsets = s.globalGet(["printerParameters", "extruderOffsets"])
|
||||
if extruder >= len(extruder_offsets):
|
||||
return 0.0
|
||||
if axis.lower() not in ("x", "y"):
|
||||
return 0.0
|
||||
return extruder_offsets[extruder][axis.lower()]
|
||||
|
||||
def get_profile_string(self):
|
||||
import base64
|
||||
import zlib
|
||||
|
|
@ -712,7 +704,7 @@ class Profile(object):
|
|||
return pre + str(f)
|
||||
|
||||
def get_gcode(self, key):
|
||||
extruder_count = s.globalGetInt(["printerParameters", "numExtruders"])
|
||||
extruder_count = self.get_int("extruder_amount")
|
||||
|
||||
prefix = ""
|
||||
postfix = ""
|
||||
|
|
@ -796,7 +788,7 @@ class Profile(object):
|
|||
return int(math.ceil(solid_thickness / (layer_height - 0.0001)))
|
||||
|
||||
def calculate_minimal_extruder_count(self):
|
||||
extruder_count = s.globalGetInt(["printerParameters", "numExtruders"])
|
||||
extruder_count = self.get("extruder_amount")
|
||||
if extruder_count < 2:
|
||||
return 1
|
||||
if self.get("support") == SupportLocationTypes.NONE:
|
||||
|
|
@ -810,7 +802,7 @@ class Profile(object):
|
|||
edge_width, line_count = self.calculate_edge_width_and_line_count()
|
||||
solid_layer_count = self.calculate_solid_layer_count()
|
||||
|
||||
extruder_count = s.globalGetInt(["printerParameters", "numExtruders"])
|
||||
extruder_count = self.get_int("extruder_amount")
|
||||
minimal_extruder_count = self.calculate_minimal_extruder_count()
|
||||
|
||||
settings = {
|
||||
|
|
@ -868,7 +860,7 @@ class Profile(object):
|
|||
|
||||
for extruder in range(1, extruder_count):
|
||||
for axis in ("x", "y"):
|
||||
settings["extruderOffset[{extruder}].{axis}".format(extruder=extruder, axis=axis.upper())] = self.get_machine_extruder_offset(extruder, axis)
|
||||
settings["extruderOffset[{extruder}].{axis}".format(extruder=extruder, axis=axis.upper())] = self.get("extruder_offset_{axis}{extruder}".format(extruder=extruder, axis=axis.lower()))
|
||||
|
||||
fanFullHeight = self.get_microns("fan_full_height")
|
||||
settings["fanFullOnLayerNr"] = (fanFullHeight - settings["initialLayerThickness"] - 1) / settings["layerThickness"] + 1
|
||||
|
|
|
|||
|
|
@ -197,15 +197,17 @@ class Printer():
|
|||
self._comm.sendCommand(command)
|
||||
|
||||
def jog(self, axis, amount):
|
||||
movementSpeed = settings().get(["printerParameters", "movementSpeed", ["x", "y", "z"]], asdict=True)
|
||||
self.commands(["G91", "G1 %s%.4f F%d" % (axis.upper(), amount, movementSpeed[axis]), "G90"])
|
||||
printer_profile = self._printerProfileManager.get_current_or_default()
|
||||
movement_speed = printer_profile["axes"][axis]["speed"]
|
||||
self.commands(["G91", "G1 %s%.4f F%d" % (axis.upper(), amount, movement_speed), "G90"])
|
||||
|
||||
def home(self, axes):
|
||||
self.commands(["G91", "G28 %s" % " ".join(map(lambda x: "%s0" % x.upper(), axes)), "G90"])
|
||||
|
||||
def extrude(self, amount):
|
||||
extrusionSpeed = settings().get(["printerParameters", "movementSpeed", "e"])
|
||||
self.commands(["G91", "G1 E%s F%d" % (amount, extrusionSpeed), "G90"])
|
||||
printer_profile = self._printerProfileManager.get_current_or_default()
|
||||
extrusion_speed = printer_profile["axes"]["e"]["speed"]
|
||||
self.commands(["G91", "G1 E%s F%d" % (amount, extrusion_speed), "G90"])
|
||||
|
||||
def changeTool(self, tool):
|
||||
try:
|
||||
|
|
@ -216,7 +218,9 @@ class Printer():
|
|||
|
||||
def setTemperature(self, type, value):
|
||||
if type.startswith("tool"):
|
||||
if settings().getInt(["printerParameters", "numExtruders"]) > 1:
|
||||
printer_profile = self._printerProfileManager.get_current_or_default()
|
||||
extruder_count = printer_profile["extruder"]["count"]
|
||||
if extruder_count > 1:
|
||||
try:
|
||||
toolNum = int(type[len("tool"):])
|
||||
self.command("M104 T%d S%f" % (toolNum, value))
|
||||
|
|
@ -301,9 +305,12 @@ class Printer():
|
|||
self._comm.cancelPrint()
|
||||
|
||||
if disableMotorsAndHeater:
|
||||
printer_profile = self._printerProfileManager.get_current_or_default()
|
||||
extruder_count = printer_profile["extruder"]["count"]
|
||||
|
||||
# disable motors, switch off hotends, bed and fan
|
||||
commands = ["M84"]
|
||||
commands.extend(map(lambda x: "M104 T%d S0" % x, range(settings().getInt(["printerParameters", "numExtruders"]))))
|
||||
commands.extend(map(lambda x: "M104 T%d S0" % x, range(extruder_count)))
|
||||
commands.extend(["M140 S0", "M106 S0"])
|
||||
self.commands(commands)
|
||||
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ class Server():
|
|||
slicingManager = octoprint.slicing.SlicingManager(settings().getBaseFolder("slicingProfiles"), printerProfileManager)
|
||||
storage_managers = dict()
|
||||
storage_managers[octoprint.filemanager.FileDestinations.LOCAL] = octoprint.filemanager.storage.LocalFileStorage(settings().getBaseFolder("uploads"))
|
||||
fileManager = octoprint.filemanager.FileManager(analysisQueue, slicingManager, initial_storage_managers=storage_managers)
|
||||
fileManager = octoprint.filemanager.FileManager(analysisQueue, slicingManager, printerProfileManager, initial_storage_managers=storage_managers)
|
||||
printer = Printer(fileManager, analysisQueue, printerProfileManager)
|
||||
appSessionManager = util.flask.AppSessionManager()
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@ import octoprint.plugin
|
|||
def getSettings():
|
||||
s = settings()
|
||||
|
||||
[movementSpeedX, movementSpeedY, movementSpeedZ, movementSpeedE] \
|
||||
= s.get(["printerParameters", "movementSpeed", ["x", "y", "z", "e"]])
|
||||
|
||||
connectionOptions = getConnectionOptions()
|
||||
|
||||
data = {
|
||||
|
|
@ -43,14 +40,6 @@ def getSettings():
|
|||
"color": s.get(["appearance", "color"])
|
||||
},
|
||||
"printer": {
|
||||
"movementSpeedX": movementSpeedX,
|
||||
"movementSpeedY": movementSpeedY,
|
||||
"movementSpeedZ": movementSpeedZ,
|
||||
"movementSpeedE": movementSpeedE,
|
||||
"invertAxes": s.get(["printerParameters", "invertAxes"]),
|
||||
"numExtruders": s.get(["printerParameters", "numExtruders"]),
|
||||
"extruderOffsets": s.get(["printerParameters", "extruderOffsets"]),
|
||||
"bedDimensions": s.get(["printerParameters", "bedDimensions"]),
|
||||
"defaultExtrusionLength": s.getInt(["printerParameters", "defaultExtrusionLength"])
|
||||
},
|
||||
"webcam": {
|
||||
|
|
@ -140,14 +129,6 @@ def setSettings():
|
|||
if "color" in data["appearance"].keys(): s.set(["appearance", "color"], data["appearance"]["color"])
|
||||
|
||||
if "printer" in data.keys():
|
||||
if "movementSpeedX" in data["printer"].keys(): s.setInt(["printerParameters", "movementSpeed", "x"], data["printer"]["movementSpeedX"])
|
||||
if "movementSpeedY" in data["printer"].keys(): s.setInt(["printerParameters", "movementSpeed", "y"], data["printer"]["movementSpeedY"])
|
||||
if "movementSpeedZ" in data["printer"].keys(): s.setInt(["printerParameters", "movementSpeed", "z"], data["printer"]["movementSpeedZ"])
|
||||
if "movementSpeedE" in data["printer"].keys(): s.setInt(["printerParameters", "movementSpeed", "e"], data["printer"]["movementSpeedE"])
|
||||
if "invertAxes" in data["printer"].keys(): s.set(["printerParameters", "invertAxes"], data["printer"]["invertAxes"])
|
||||
if "numExtruders" in data["printer"].keys(): s.setInt(["printerParameters", "numExtruders"], data["printer"]["numExtruders"])
|
||||
if "extruderOffsets" in data["printer"].keys(): s.set(["printerParameters", "extruderOffsets"], data["printer"]["extruderOffsets"])
|
||||
if "bedDimensions" in data["printer"].keys(): s.set(["printerParameters", "bedDimensions"], data["printer"]["bedDimensions"])
|
||||
if "defaultExtrusionLength" in data["printer"]: s.setInt(["printerParameters", "defaultExtrusionLength"], data["printer"]["defaultExtrusionLength"])
|
||||
|
||||
if "webcam" in data.keys():
|
||||
|
|
|
|||
|
|
@ -26,10 +26,14 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
|
|||
|
||||
self.feedbackControlLookup = {};
|
||||
|
||||
self.settings.printer_numExtruders.subscribe(function(oldVal, newVal) {
|
||||
self.settings.printerProfiles.currentProfileData.subscribe(function() {
|
||||
self._updateExtruderCount();
|
||||
self.settings.printerProfiles.currentProfileData().extruder.count.subscribe(self._updateExtruderCount);
|
||||
});
|
||||
self._updateExtruderCount = function() {
|
||||
var tools = [];
|
||||
|
||||
var numExtruders = self.settings.printer_numExtruders();
|
||||
var numExtruders = self.settings.printerProfiles.currentProfileData().extruder.count();
|
||||
if (numExtruders > 1) {
|
||||
// multiple extruders
|
||||
for (var extruder = 0; extruder < numExtruders; extruder++) {
|
||||
|
|
@ -45,7 +49,7 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
|
|||
}
|
||||
|
||||
self.tools(tools);
|
||||
});
|
||||
};
|
||||
|
||||
self.fromCurrentData = function(data) {
|
||||
self._processStateData(data.state);
|
||||
|
|
|
|||
|
|
@ -46,83 +46,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV
|
|||
}
|
||||
};
|
||||
|
||||
self.printer_movementSpeedX = ko.observable(undefined);
|
||||
self.printer_movementSpeedY = ko.observable(undefined);
|
||||
self.printer_movementSpeedZ = ko.observable(undefined);
|
||||
self.printer_movementSpeedE = ko.observable(undefined);
|
||||
self.printer_invertAxes = ko.observable(undefined);
|
||||
self.printer_numExtruders = ko.observable(undefined);
|
||||
self.printer_defaultExtrusionLength = ko.observable(undefined);
|
||||
|
||||
self._printer_extruderOffsets = ko.observableArray([]);
|
||||
self.printer_extruderOffsets = ko.computed({
|
||||
read: function() {
|
||||
var extruderOffsets = self._printer_extruderOffsets();
|
||||
var result = [];
|
||||
for (var i = 0; i < extruderOffsets.length; i++) {
|
||||
result[i] = {
|
||||
x: parseFloat(extruderOffsets[i].x()),
|
||||
y: parseFloat(extruderOffsets[i].y())
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
write: function(value) {
|
||||
var result = [];
|
||||
if (value && Array.isArray(value)) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
result[i] = {
|
||||
x: ko.observable(value[i].x),
|
||||
y: ko.observable(value[i].y)
|
||||
}
|
||||
}
|
||||
}
|
||||
self._printer_extruderOffsets(result);
|
||||
},
|
||||
owner: self
|
||||
});
|
||||
self.ko_printer_extruderOffsets = ko.computed(function() {
|
||||
var extruderOffsets = self._printer_extruderOffsets();
|
||||
var numExtruders = self.printer_numExtruders();
|
||||
if (!numExtruders) {
|
||||
numExtruders = 1;
|
||||
}
|
||||
|
||||
if (numExtruders > extruderOffsets.length) {
|
||||
for (var i = extruderOffsets.length; i < numExtruders; i++) {
|
||||
extruderOffsets[i] = {
|
||||
x: ko.observable(0),
|
||||
y: ko.observable(0)
|
||||
}
|
||||
}
|
||||
self._printer_extruderOffsets(extruderOffsets);
|
||||
}
|
||||
|
||||
return extruderOffsets.slice(0, numExtruders);
|
||||
});
|
||||
|
||||
self.printer_bedDimensionX = ko.observable(undefined);
|
||||
self.printer_bedDimensionY = ko.observable(undefined);
|
||||
self.printer_bedDimensionR = ko.observable(undefined);
|
||||
self.printer_bedCircular = ko.observable(undefined);
|
||||
self.printer_bedDimensions = ko.computed({
|
||||
read: function () {
|
||||
return {
|
||||
x: parseFloat(self.printer_bedDimensionX()),
|
||||
y: parseFloat(self.printer_bedDimensionY()),
|
||||
r: parseFloat(self.printer_bedDimensionR()),
|
||||
circular: self.printer_bedCircular()
|
||||
};
|
||||
},
|
||||
write: function(value) {
|
||||
self.printer_bedDimensionX(value.x);
|
||||
self.printer_bedDimensionY(value.y);
|
||||
self.printer_bedDimensionR(value.r);
|
||||
self.printer_bedCircular(value.circular);
|
||||
},
|
||||
owner: self
|
||||
});
|
||||
|
||||
self.webcam_streamUrl = ko.observable(undefined);
|
||||
self.webcam_snapshotUrl = ko.observable(undefined);
|
||||
self.webcam_ffmpegPath = ko.observable(undefined);
|
||||
|
|
@ -186,31 +111,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV
|
|||
self.terminalFilters.remove(filter);
|
||||
};
|
||||
|
||||
self.getPrinterInvertAxis = function(axis) {
|
||||
return _.contains((self.printer_invertAxes() || []), axis.toLowerCase());
|
||||
};
|
||||
|
||||
self.setPrinterInvertAxis = function(axis, value) {
|
||||
var currInvert = self.printer_invertAxes() || [];
|
||||
var currValue = self.getPrinterInvertAxis(axis);
|
||||
if (value && !currValue) {
|
||||
currInvert.push(axis.toLowerCase());
|
||||
} else if (!value && currValue) {
|
||||
currInvert = _.without(currInvert, axis.toLowerCase());
|
||||
}
|
||||
self.printer_invertAxes(currInvert);
|
||||
};
|
||||
|
||||
self.koInvertAxis = function (axis) { return ko.computed({
|
||||
read: function () { return self.getPrinterInvertAxis(axis); },
|
||||
write: function (value) { self.setPrinterInvertAxis(axis, value); },
|
||||
owner: self
|
||||
})};
|
||||
|
||||
self.printer_invertX = self.koInvertAxis('x');
|
||||
self.printer_invertY = self.koInvertAxis('y');
|
||||
self.printer_invertZ = self.koInvertAxis('z');
|
||||
|
||||
self.onSettingsShown = function() {
|
||||
self.requestData();
|
||||
};
|
||||
|
|
@ -241,14 +141,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV
|
|||
self.appearance_name(response.appearance.name);
|
||||
self.appearance_color(response.appearance.color);
|
||||
|
||||
self.printer_movementSpeedX(response.printer.movementSpeedX);
|
||||
self.printer_movementSpeedY(response.printer.movementSpeedY);
|
||||
self.printer_movementSpeedZ(response.printer.movementSpeedZ);
|
||||
self.printer_movementSpeedE(response.printer.movementSpeedE);
|
||||
self.printer_invertAxes(response.printer.invertAxes);
|
||||
self.printer_numExtruders(response.printer.numExtruders);
|
||||
self.printer_extruderOffsets(response.printer.extruderOffsets);
|
||||
self.printer_bedDimensions(response.printer.bedDimensions);
|
||||
self.printer_defaultExtrusionLength(response.printer.defaultExtrusionLength);
|
||||
|
||||
self.webcam_streamUrl(response.webcam.streamUrl);
|
||||
|
|
@ -311,14 +203,6 @@ function SettingsViewModel(loginStateViewModel, usersViewModel, printerProfilesV
|
|||
"color": self.appearance_color()
|
||||
},
|
||||
"printer": {
|
||||
"movementSpeedX": self.printer_movementSpeedX(),
|
||||
"movementSpeedY": self.printer_movementSpeedY(),
|
||||
"movementSpeedZ": self.printer_movementSpeedZ(),
|
||||
"movementSpeedE": self.printer_movementSpeedE(),
|
||||
"invertAxes": self.printer_invertAxes(),
|
||||
"numExtruders": self.printer_numExtruders(),
|
||||
"extruderOffsets": self.printer_extruderOffsets(),
|
||||
"bedDimensions": self.printer_bedDimensions(),
|
||||
"defaultExtrusionLength": self.printer_defaultExtrusionLength()
|
||||
},
|
||||
"webcam": {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ function TemperatureViewModel(loginStateViewModel, settingsViewModel) {
|
|||
var tools = self.tools();
|
||||
|
||||
// tools
|
||||
var numExtruders = self.settingsViewModel.printer_numExtruders();
|
||||
var numExtruders = self.settingsViewModel.printerProfiles.currentProfileData().extruder.count();
|
||||
if (numExtruders && numExtruders > 1) {
|
||||
// multiple extruders
|
||||
for (var extruder = 0; extruder < numExtruders; extruder++) {
|
||||
|
|
@ -73,7 +73,10 @@ function TemperatureViewModel(loginStateViewModel, settingsViewModel) {
|
|||
self.heaterOptions(heaterOptions);
|
||||
self.tools(tools);
|
||||
};
|
||||
self.settingsViewModel.printer_numExtruders.subscribe(self._numExtrudersUpdated);
|
||||
self.settingsViewModel.printerProfiles.currentProfileData.subscribe(function() {
|
||||
self._numExtrudersUpdated();
|
||||
self.settingsViewModel.printerProfiles.currentProfileData().extruder.count.subscribe(self._numExtrudersUpdated);
|
||||
});
|
||||
|
||||
self.temperatures = [];
|
||||
self.plotOptions = {
|
||||
|
|
|
|||
|
|
@ -31,17 +31,17 @@ class gcode(object):
|
|||
self._abort = False
|
||||
self._filamentDiameter = 0
|
||||
|
||||
def load(self, filename):
|
||||
def load(self, filename, printer_profile):
|
||||
if os.path.isfile(filename):
|
||||
self.filename = filename
|
||||
self._fileSize = os.stat(filename).st_size
|
||||
with open(filename, "r") as f:
|
||||
self._load(f)
|
||||
self._load(f, printer_profile)
|
||||
|
||||
def abort(self):
|
||||
self._abort = True
|
||||
|
||||
def _load(self, gcodeFile):
|
||||
def _load(self, gcodeFile, printer_profile):
|
||||
filePos = 0
|
||||
pos = [0.0, 0.0, 0.0]
|
||||
posOffset = [0.0, 0.0, 0.0]
|
||||
|
|
@ -53,8 +53,8 @@ class gcode(object):
|
|||
absoluteE = True
|
||||
scale = 1.0
|
||||
posAbs = True
|
||||
feedRateXY = settings().getFloat(["printerParameters", "movementSpeed", "x"])
|
||||
offsets = settings().get(["printerParameters", "extruderOffsets"])
|
||||
feedRateXY = min(printer_profile["axes"]["x"], printer_profile["axes"]["y"])
|
||||
offsets = printer_profile["extruder"]["offsets"]
|
||||
|
||||
for line in gcodeFile:
|
||||
if self._abort:
|
||||
|
|
@ -198,13 +198,13 @@ class gcode(object):
|
|||
if T > settings().getInt(["gcodeAnalysis", "maxExtruders"]):
|
||||
self._logger.warn("GCODE tried to select tool %d, that looks wrong, ignoring for GCODE analysis" % T)
|
||||
else:
|
||||
posOffset[0] -= offsets[currentExtruder]["x"] if currentExtruder < len(offsets) else 0
|
||||
posOffset[1] -= offsets[currentExtruder]["y"] if currentExtruder < len(offsets) else 0
|
||||
posOffset[0] -= offsets[currentExtruder][0] if currentExtruder < len(offsets) else 0
|
||||
posOffset[1] -= offsets[currentExtruder][1] if currentExtruder < len(offsets) else 0
|
||||
|
||||
currentExtruder = T
|
||||
|
||||
posOffset[0] += offsets[currentExtruder]["x"] if currentExtruder < len(offsets) else 0
|
||||
posOffset[1] += offsets[currentExtruder]["y"] if currentExtruder < len(offsets) else 0
|
||||
posOffset[0] += offsets[currentExtruder][0] if currentExtruder < len(offsets) else 0
|
||||
posOffset[1] += offsets[currentExtruder][1] if currentExtruder < len(offsets) else 0
|
||||
|
||||
if len(currentE) <= currentExtruder:
|
||||
for i in range(len(currentE), currentExtruder + 1):
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class FileManagerTest(unittest.TestCase):
|
|||
def setUp(self):
|
||||
import octoprint.slicing
|
||||
import octoprint.filemanager.storage
|
||||
import octoprint.printer.profile
|
||||
|
||||
self.addCleanup(self.cleanUp)
|
||||
|
||||
|
|
@ -29,13 +30,15 @@ class FileManagerTest(unittest.TestCase):
|
|||
|
||||
self.slicing_manager = mock.MagicMock(spec=octoprint.slicing.SlicingManager)
|
||||
|
||||
self.printer_profile_manager = mock.MagicMock(spec=octoprint.printer.profile.PrinterProfileManager)
|
||||
|
||||
self.local_storage = mock.MagicMock(spec=octoprint.filemanager.storage.LocalFileStorage)
|
||||
self.local_storage.analysis_backlog = iter([])
|
||||
|
||||
self.storage_managers = dict()
|
||||
self.storage_managers[octoprint.filemanager.FileDestinations.LOCAL] = self.local_storage
|
||||
|
||||
self.file_manager = octoprint.filemanager.FileManager(self.analysis_queue, self.slicing_manager, initial_storage_managers=self.storage_managers)
|
||||
self.file_manager = octoprint.filemanager.FileManager(self.analysis_queue, self.slicing_manager, self.printer_profile_manager, initial_storage_managers=self.storage_managers)
|
||||
|
||||
def cleanUp(self):
|
||||
self.event_manager_patcher.stop()
|
||||
|
|
@ -46,10 +49,13 @@ class FileManagerTest(unittest.TestCase):
|
|||
self.local_storage.add_file.return_value = ("", "test.file")
|
||||
self.local_storage.get_absolute_path.return_value = "prefix/test.file"
|
||||
|
||||
test_profile = dict(id="_default", name="My Default Profile")
|
||||
self.printer_profile_manager.get_current_or_default.return_value = test_profile
|
||||
|
||||
file_path = self.file_manager.add_file(octoprint.filemanager.FileDestinations.LOCAL, "test.file", wrapper)
|
||||
|
||||
self.assertEquals(("", "test.file"), file_path)
|
||||
self.local_storage.add_file.assert_called_once_with("test.file", wrapper, allow_overwrite=False, links=None)
|
||||
self.local_storage.add_file.assert_called_once_with("test.file", wrapper, printer_profile=test_profile, allow_overwrite=False, links=None)
|
||||
self.fire_event.assert_called_once_with(octoprint.filemanager.Events.UPDATED_FILES, dict(type="printables"))
|
||||
|
||||
def test_remove_file(self):
|
||||
|
|
@ -114,6 +120,11 @@ class FileManagerTest(unittest.TestCase):
|
|||
metadata = dict(hash="aabbccddeeff")
|
||||
self.local_storage.get_metadata.return_value = metadata
|
||||
|
||||
# mock printer profile
|
||||
expected_printer_profile = dict(id="_default", name="My Default Profile")
|
||||
self.printer_profile_manager.get_current_or_default.return_value = expected_printer_profile
|
||||
self.printer_profile_manager.get.return_value = None
|
||||
|
||||
# mock get_absolute_path method on local storage
|
||||
def get_absolute_path(path):
|
||||
if isinstance(path, tuple):
|
||||
|
|
@ -131,13 +142,13 @@ class FileManagerTest(unittest.TestCase):
|
|||
self.local_storage.split_path.side_effect = split_path
|
||||
|
||||
# mock add_file method on local storage
|
||||
def add_file(path, file_obj, links=None, allow_overwrite=False):
|
||||
def add_file(path, file_obj, printer_profile=None, links=None, allow_overwrite=False):
|
||||
file_obj.save("prefix/" + path)
|
||||
return "", path
|
||||
self.local_storage.add_file.side_effect = add_file
|
||||
|
||||
# mock slice method on slicing manager
|
||||
def slice(slicer_name, source_path, dest_path, profile, done_cb, callback_args=None, overrides=None, on_progress=None, on_progress_args=None, on_progress_kwargs=None):
|
||||
def slice(slicer_name, source_path, dest_path, profile, done_cb, printer_profile_id=None, callback_args=None, overrides=None, on_progress=None, on_progress_args=None, on_progress_kwargs=None):
|
||||
self.assertEquals("some_slicer", slicer_name)
|
||||
self.assertEquals("prefix/source.file", source_path)
|
||||
self.assertEquals("tmp.file", dest_path)
|
||||
|
|
@ -163,7 +174,7 @@ class FileManagerTest(unittest.TestCase):
|
|||
|
||||
# assert that model links were added
|
||||
expected_links = [("model", dict(name="source.file"))]
|
||||
self.local_storage.add_file.assert_called_once_with("dest.file", mock.ANY, allow_overwrite=True, links=expected_links)
|
||||
self.local_storage.add_file.assert_called_once_with("dest.file", mock.ANY, printer_profile=expected_printer_profile, allow_overwrite=True, links=expected_links)
|
||||
|
||||
# assert that the generated gcode was manipulated as required
|
||||
expected_open_calls = [mock.call("prefix/dest.file", "w"), mock.call("tmp.file", "r")]
|
||||
|
|
@ -203,7 +214,7 @@ class FileManagerTest(unittest.TestCase):
|
|||
self.local_storage.get_absolute_path.side_effect = get_absolute_path
|
||||
|
||||
# mock slice method on slicing manager
|
||||
def slice(slicer_name, source_path, dest_path, profile, done_cb, callback_args=None, overrides=None, on_progress=None, on_progress_args=None, on_progress_kwargs=None):
|
||||
def slice(slicer_name, source_path, dest_path, profile, done_cb, printer_profile_id=None, callback_args=None, overrides=None, on_progress=None, on_progress_args=None, on_progress_kwargs=None):
|
||||
self.assertEquals("some_slicer", slicer_name)
|
||||
self.assertEquals("prefix/source.file", source_path)
|
||||
self.assertEquals("tmp.file", dest_path)
|
||||
|
|
|
|||
Loading…
Reference in a new issue