Fully switched to printer profiles

This commit is contained in:
Gina Häußge 2014-12-02 11:30:00 +01:00
parent 05e54fa0c6
commit 2ea1b9df6c
12 changed files with 114 additions and 192 deletions

View file

@ -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"))

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -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():

View file

@ -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);

View file

@ -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": {

View file

@ -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 = {

View file

@ -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):

View file

@ -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)