diff --git a/README.md b/README.md index 39bfa53..44c5bdb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,23 @@ # OctoPrint-CalibrationTools -**TODO:** Describe what your plugin does. +A set of tools to help users with calibration process. +Supported tunings: + +- E Steps - calibrating number of steps/mm for E extruder; +- XYZ Steps - calibrating number of steps/mm for axes X, Y and Z; +- PID Auto-tune - calibration Proportional gain, Integral gain and Derivative values for hot-end and heated bed; + +Before start using this plugin I strongly recommend reading some documentation about tunning [teachingtechyt.github.io](https://teachingtechyt.github.io/calibration.html) + +## Supported frameworks + +- Marlin 2.x + +## Screens + +![E-Steps](assets/eSteps.png) +![X-Y-Z Steps](assets/XYZSteps.png) +![PID Autotune](assets/PID-autotune.png) ## Setup @@ -9,9 +26,6 @@ or manually using this URL: https://github.com/SergiuToporjinschi/OctoPrint-CalibrationTools/archive/master.zip -**TODO:** Describe how to install your plugin, if more needs to be done than just installing it via pip or through -the plugin manager. - ## Configuration -**TODO:** Describe your plugin's configuration options (if any). +You can set the default values for each tuning process. diff --git a/assets/PID-autotune.png b/assets/PID-autotune.png new file mode 100644 index 0000000..cf51e64 Binary files /dev/null and b/assets/PID-autotune.png differ diff --git a/assets/XYZSteps.png b/assets/XYZSteps.png new file mode 100644 index 0000000..f3eb6f0 Binary files /dev/null and b/assets/XYZSteps.png differ diff --git a/assets/eSteps.png b/assets/eSteps.png new file mode 100644 index 0000000..dca7509 Binary files /dev/null and b/assets/eSteps.png differ diff --git a/octoprint_CalibrationTools/static/js/EStepsViewModel.js b/octoprint_CalibrationTools/static/js/EStepsViewModel.js index c3298f8..9027acb 100644 --- a/octoprint_CalibrationTools/static/js/EStepsViewModel.js +++ b/octoprint_CalibrationTools/static/js/EStepsViewModel.js @@ -6,6 +6,14 @@ $(function () { self.controlViewModel = parameters[2]; self.terminalViewModel = parameters[3]; self.access = parameters[4]; + self.generalVM = parameters[5]; + + self.columnLabelCls = ko.computed(function () { + return self.generalVM.isSmall() ? "span4" : "span3"; + }); + self.columnFieldCls = ko.computed(function () { + return self.generalVM.isSmall() ? "span8" : "span9"; + }); self.is_admin = ko.observable(false); self.steps = ko.observable(); @@ -69,7 +77,6 @@ $(function () { text: "Heating nuzzle has started!!!
When extrusion stops you have to fulfil Length after extrusion and save the new value ", type: "warning" }); - console.log(response); }).fail(function (response) { new PNotify({ title: "Error on starting extrusion ", @@ -109,7 +116,7 @@ $(function () { // This is a list of dependencies to inject into the plugin, the order which you request // here is the order in which the dependencies will be injected into your view model upon // instantiation via the parameters argument - dependencies: ["loginStateViewModel", "settingsViewModel", "controlViewModel", "terminalViewModel", "accessViewModel"], + dependencies: ["loginStateViewModel", "settingsViewModel", "controlViewModel", "terminalViewModel", "accessViewModel", "calibrationToolsGeneralViewModel"], // Finally, this is the list of selectors for all elements we want this view model to be bound to. elements: ["#calibration_eSteps"] }); diff --git a/octoprint_CalibrationTools/static/js/GeneralViewModel.js b/octoprint_CalibrationTools/static/js/GeneralViewModel.js index 00d4440..b4d398c 100644 --- a/octoprint_CalibrationTools/static/js/GeneralViewModel.js +++ b/octoprint_CalibrationTools/static/js/GeneralViewModel.js @@ -9,6 +9,7 @@ $(function () { } } } + this.isSmall = ko.observable($("#tab_plugin_CalibrationTools").width() < 800); ko.extenders.numeric = function (target, options) { var returnObs = ko.pureComputed({ read: target, @@ -22,8 +23,11 @@ $(function () { returnObs(target()); return returnObs; }; + + this.onStartupComplete = function () { + this.isSmall($("#tabs_content").width() < 800); + } } - // OCTOPRINT_VIEWMODELS.push([GeneralViewModel, ["loginStateViewModel"], []]); OCTOPRINT_VIEWMODELS.push({ // This is the constructor to call for instantiating the plugin construct: CalibrationToolsGeneralViewModel, diff --git a/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js b/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js index 05d088e..5034f04 100644 --- a/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js +++ b/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js @@ -4,7 +4,13 @@ $(function () { self.loginStateViewModel = parameters[0]; self.settingsViewModel = parameters[1]; self.controlViewModel = parameters[2]; - + self.generalVM = parameters[5]; + self.columnLabelCls = ko.computed(function () { + return self.generalVM.isSmall() ? "span3" : "span3"; + }); + self.columnFieldCls = ko.computed(function () { + return self.generalVM.isSmall() ? "span9" : "span9"; + }); self.pidCurrentValues = { "hotEnd": { "P": ko.observable(0), @@ -79,7 +85,6 @@ $(function () { text: "In progress", type: "info" }); - console.log(response); }).fail(function (response) { new PNotify({ title: "Error on starting PID autotune ", @@ -102,7 +107,6 @@ $(function () { text: "In progress", type: "info" }); - console.log(response); }).fail(function (response) { new PNotify({ title: "Error on starting PID autotune ", @@ -119,7 +123,7 @@ $(function () { // This is a list of dependencies to inject into the plugin, the order which you request // here is the order in which the dependencies will be injected into your view model upon // instantiation via the parameters argument - dependencies: ["loginStateViewModel", "settingsViewModel", "controlViewModel", "terminalViewModel", "accessViewModel"], + dependencies: ["loginStateViewModel", "settingsViewModel", "controlViewModel", "terminalViewModel", "accessViewModel", "calibrationToolsGeneralViewModel"], // Finally, this is the list of selectors for all elements we want this view model to be bound to. elements: ["#calibration_pid"] }); diff --git a/octoprint_CalibrationTools/static/js/XYZStepsViewModel.js b/octoprint_CalibrationTools/static/js/XYZStepsViewModel.js index b73fe88..6050cc2 100644 --- a/octoprint_CalibrationTools/static/js/XYZStepsViewModel.js +++ b/octoprint_CalibrationTools/static/js/XYZStepsViewModel.js @@ -4,28 +4,33 @@ $(function () { self.loginStateViewModel = parameters[0]; self.settingsViewModel = parameters[1]; self.controlViewModel = parameters[2]; - generalVM = parameters[5]; - + self.generalVM = parameters[5]; + self.columnLabelCls = ko.computed(function () { + return self.generalVM.isSmall() ? "span2" : "span3"; + }); + self.columnFieldCls = ko.computed(function () { + return self.generalVM.isSmall() ? "span10" : "span9"; + }); self.eStepsXYZ = { currentSteps: { - X: ko.observable(0).extend(generalVM.decimal3(0.000)), - Y: ko.observable(0).extend(generalVM.decimal3(0.000)), - Z: ko.observable(0).extend(generalVM.decimal3(0.000)) + X: ko.observable(0).extend(self.generalVM.decimal3(0.000)), + Y: ko.observable(0).extend(self.generalVM.decimal3(0.000)), + Z: ko.observable(0).extend(self.generalVM.decimal3(0.000)) }, gCodeCubeSize: { - X: ko.observable().extend(generalVM.decimal3(22.000)), - Y: ko.observable().extend(generalVM.decimal3(22.000)), - Z: ko.observable().extend(generalVM.decimal3(22.000)) + X: ko.observable().extend(self.generalVM.decimal3(22.000)), + Y: ko.observable().extend(self.generalVM.decimal3(22.000)), + Z: ko.observable().extend(self.generalVM.decimal3(22.000)) }, printedCubeSize: { - X: ko.observable().extend(generalVM.decimal3(25.000)), - Y: ko.observable().extend(generalVM.decimal3(25.000)), - Z: ko.observable().extend(generalVM.decimal3(25.000)) + X: ko.observable().extend(self.generalVM.decimal3(25.000)), + Y: ko.observable().extend(self.generalVM.decimal3(25.000)), + Z: ko.observable().extend(self.generalVM.decimal3(25.000)) }, newSteps: { - X: ko.observable().extend(generalVM.decimal3(0.000)), - Y: ko.observable().extend(generalVM.decimal3(0.000)), - Z: ko.observable().extend(generalVM.decimal3(0.000)) + X: ko.observable().extend(self.generalVM.decimal3(0.000)), + Y: ko.observable().extend(self.generalVM.decimal3(0.000)), + Z: ko.observable().extend(self.generalVM.decimal3(0.000)) } }; @@ -69,7 +74,9 @@ $(function () { }) }; - + // self.labelColumnCss = viewModel.profitStatus = ko.pureComputed(function () { + // return "span3" $("#tab_plugin_CalibrationTools").width() < 800 + // }); self.isAdmin = ko.observable(false); diff --git a/octoprint_CalibrationTools/static/js/test.js b/octoprint_CalibrationTools/static/js/test.js deleted file mode 100644 index da537b0..0000000 --- a/octoprint_CalibrationTools/static/js/test.js +++ /dev/null @@ -1,694 +0,0 @@ -$(function () { - function AccessViewModel(parameters) { - var access = this; - access.loginState = parameters[0]; - var GROUP_ADMINS = "admins"; - var GROUP_GUESTS = "guests"; - access.users = (function () { - var self = {}; - self.listHelper = new ItemListHelper("users", { - name: function (a, b) { - if (a["name"].toLocaleLowerCase() < b["name"].toLocaleLowerCase()) - return -1; - if (a["name"].toLocaleLowerCase() > b["name"].toLocaleLowerCase()) - return 1; - return 0; - } - }, {}, "name", [], [], CONFIG_USERSPERPAGE); - self.emptyUser = { - name: "", - active: false - }; - self.currentUser = ko.observable(self.emptyUser).extend({ - notify: "always" - }); - self.editor = { - name: ko.observable(undefined), - groups: ko.observableArray([]), - permissions: ko.observableArray([]), - password: ko.observable(undefined), - repeatedPassword: ko.observable(undefined), - passwordMismatch: ko.pureComputed(function () { - return self.editor.password() !== self.editor.repeatedPassword(); - }), - apikey: ko.observable(undefined), - active: ko.observable(undefined), - permissionSelectable: function (permission) { - return true; - }, - permissionSelected: function (permission) { - var index = self.editor.permissions().indexOf(permission); - return index >= 0; - }, - togglePermission: function (permission) { - var permissions = self.editor.permissions(); - var index = permissions.indexOf(permission); - if (index < 0) { - permissions.push(permission); - } else { - permissions.splice(index, 1); - } - self.editor.permissions(permissions); - }, - groupSelected: function (group) { - var index = self.editor.groups().indexOf(group); - return index >= 0; - }, - toggleGroup: function (group) { - var groups = self.editor.groups(); - var index = groups.indexOf(group); - if (index < 0) { - groups.push(group); - } else { - groups.splice(index, 1); - } - self.editor.groups(groups); - }, - joinedGroupPermissions: function (group) { - return access.permissionList(group); - }, - header: ko.observable(undefined), - new: ko.observable(true), - confirm: undefined, - valid: ko.pureComputed(function () { - return (self.editor.name() && self.editor.name().trim() && (!self.editor.new() || (self.editor.password() && self.editor.password().trim() && !self.editor.passwordMismatch()))); - }), - dangerRestricted: function () { - return false; - }, - dangerRestrictedText: gettext("This user may not have dangerous permissions.") - }; - self.userEditorDialog = undefined; - self.changePasswordDialog = undefined; - self.currentUser.subscribe(function (newValue) { - if (newValue === undefined) { - self.editor.name(undefined); - self.editor.groups(access.groups.defaults.slice(0)); - self.editor.permissions([]); - self.editor.active(true); - self.editor.apikey(undefined); - self.editor.header(gettext("Add user")); - self.editor.new(true); - self.editor.confirm = self.confirmAddUser; - } else { - self.editor.name(newValue.name); - self.editor.groups(newValue.groups.slice(0)); - self.editor.permissions(newValue.permissions.slice(0)); - self.editor.active(newValue.active); - self.editor.apikey(newValue.apikey); - self.editor.header(_.sprintf(gettext('Edit user "%(name)s"'), { - name: newValue.name - })); - self.editor.new(false); - self.editor.confirm = self.confirmEditUser; - } - self.editor.password(undefined); - self.editor.repeatedPassword(undefined); - }); - self.requestData = function () { - if (!CONFIG_ACCESS_CONTROL) - return; - if (!access.loginState.hasPermissionKo(access.permissions.ADMIN)) - return; - return OctoPrint.access.users.list().done(self.fromResponse); - } - ; - self.fromResponse = function (response) { - self.listHelper.updateItems(response.users); - } - ; - self.showAddUserDialog = function () { - if (!CONFIG_ACCESS_CONTROL) - return; - self.currentUser(undefined); - $('ul.nav-pills a[data-toggle="tab"]:first', self.userEditorDialog).tab("show"); - self.userEditorDialog.modal({ - minHeight: function () { - return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); - } - }).css({ - "margin-left": function () { - return -($(this).width() / 2); - } - }); - } - ; - self.confirmAddUser = function () { - if (!CONFIG_ACCESS_CONTROL) - return; - var user = { - name: self.editor.name(), - password: self.editor.password(), - groups: self.editor.groups(), - permissions: self.editor.permissions(), - active: self.editor.active() - }; - self.addUser(user).done(function () { - self.currentUser(undefined); - self.userEditorDialog.modal("hide"); - }); - } - ; - self.showEditUserDialog = function (user) { - if (!CONFIG_ACCESS_CONTROL) - return; - var process = function (user) { - self.currentUser(user); - $('ul.nav-pills a[data-toggle="tab"]:first', self.userEditorDialog).tab("show"); - self.userEditorDialog.modal({ - minHeight: function () { - return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); - } - }).css({ - "margin-left": function () { - return -($(this).width() / 2); - } - }); - }; - OctoPrint.users.get(user.name).done(function (data) { - process(data); - }).fail(function () { - log.warn("Could not fetch current user data, proceeding with client side data copy"); - process(user); - }); - } - ; - self.confirmEditUser = function () { - if (!CONFIG_ACCESS_CONTROL) - return; - var user = self.currentUser(); - user.active = self.editor.active(); - user.groups = self.editor.groups(); - user.permissions = self.editor.permissions(); - self.updateUser(user).done(function () { - self.currentUser(undefined); - self.userEditorDialog.modal("hide"); - }); - } - ; - self.showChangePasswordDialog = function (user) { - if (!CONFIG_ACCESS_CONTROL) - return; - self.currentUser(user); - self.changePasswordDialog.modal("show"); - } - ; - self.confirmChangePassword = function () { - if (!CONFIG_ACCESS_CONTROL) - return; - self.updatePassword(self.currentUser().name, self.editor.password()).done(function () { - self.currentUser(undefined); - self.changePasswordDialog.modal("hide"); - }); - } - ; - self.confirmGenerateApikey = function () { - if (!CONFIG_ACCESS_CONTROL) - return; - self.generateApikey(self.currentUser().name).done(function (response) { - self._updateApikey(response.apikey); - }); - } - ; - self.copyApikey = function () { - copyToClipboard(self.editor.apikey()); - } - ; - self._updateApikey = function (apikey) { - self.editor.apikey(apikey); - self.requestData(); - } - ; - self.confirmDeleteApikey = function () { - if (!CONFIG_ACCESS_CONTROL) - return; - self.deleteApikey(self.currentUser().name).done(function () { - self._updateApikey(undefined); - }); - } - ; - self.onStartup = function () { - self.userEditorDialog = $("#settings-usersEditorDialog"); - self.changePasswordDialog = $("#settings-usersDialogChangePassword"); - } - ; - self.addUser = function (user) { - if (!user) { - throw OctoPrint.InvalidArgumentError("user must be set"); - } - if (!access.loginState.hasPermissionKo(access.permissions.ADMIN)) - return $.Deferred().reject("You are not authorized to perform this action").promise(); - return OctoPrint.access.users.add(user).done(self.fromResponse); - } - ; - self.removeUser = function (user) { - if (!user) { - throw OctoPrint.InvalidArgumentError("user must be set"); - } - if (!access.loginState.hasPermissionKo(access.permissions.ADMIN)) - return $.Deferred().reject("You are not authorized to perform this action").promise(); - if (user.name === access.loginState.username()) { - new PNotify({ - title: gettext("Not possible"), - text: gettext("You may not delete your own account."), - type: "error" - }); - return $.Deferred().reject("You may not delete your own account").promise(); - } - showConfirmationDialog({ - title: gettext("Are you sure?"), - message: _.sprintf(gettext('You are about to delete the user "%(name)s".'), { - name: user.name - }), - proceed: gettext("Delete"), - onproceed: function () { - OctoPrint.access.users.delete(user.name).done(self.fromResponse); - } - }); - } - ; - self.updateUser = function (user) { - if (!user) { - throw OctoPrint.InvalidArgumentError("user must be set"); - } - return OctoPrint.access.users.update(user.name, user.active, user.admin, user.permissions, user.groups).done(self.fromResponse); - } - ; - self.updatePassword = function (username, password) { - return OctoPrint.access.users.changePassword(username, password); - } - ; - self.generateApikey = function (username) { - return OctoPrint.access.users.generateApiKey(username).done(function () { - self.requestData(); - }); - } - ; - self.deleteApikey = function (username) { - return OctoPrint.access.users.resetApiKey(username); - } - ; - return self; - } - )(); - access.groups = (function () { - var self = {}; - self.listHelper = new ItemListHelper("groups", { - name: function (a, b) { - if (a["name"].toLocaleLowerCase() < b["name"].toLocaleLowerCase()) - return -1; - if (a["name"].toLocaleLowerCase() > b["name"].toLocaleLowerCase()) - return 1; - return 0; - } - }, {}, "name", [], [], CONFIG_GROUPSPERPAGE); - self.groupsList = self.listHelper.items; - self.lookup = {}; - self.defaults = []; - self.emptyGroup = { - name: "" - }; - self.currentGroup = ko.observable(self.emptyGroup); - self.editor = { - key: ko.observable(undefined), - name: ko.observable(undefined), - description: ko.observable(undefined), - permissions: ko.observableArray([]), - subgroups: ko.observableArray([]), - default: ko.observable(false), - permissionSelectable: function (permission) { - return self.editor.key() !== GROUP_GUESTS || !permission.dangerous; - }, - permissionSelected: function (permission) { - var index = self.editor.permissions().indexOf(permission); - return index >= 0; - }, - togglePermission: function (permission) { - var permissions = self.editor.permissions(); - var index = permissions.indexOf(permission); - if (index < 0) { - permissions.push(permission); - } else { - permissions.splice(index, 1); - } - self.editor.permissions(permissions); - }, - subgroupSelectable: function (subgroup) { - return (self.editor.key() !== subgroup.key && (self.editor.key() !== GROUP_GUESTS || !subgroup.dangerous)); - }, - subgroupSelected: function (subgroup) { - var index = self.editor.subgroups().indexOf(subgroup); - return index >= 0; - }, - toggleSubgroup: function (subgroup) { - var subgroups = self.editor.subgroups(); - var index = subgroups.indexOf(subgroup); - if (index < 0) { - subgroups.push(subgroup); - } else { - subgroups.splice(index, 1); - } - self.editor.subgroups(subgroups); - }, - joinedGroupPermissions: function (group) { - return access.permissionList(group); - }, - header: ko.observable(undefined), - new: ko.observable(true), - confirm: undefined, - valid: ko.pureComputed(function () { - return self.editor.name() && self.editor.name().trim(); - }), - dangerRestricted: function () { - return self.editor.key() === GROUP_GUESTS; - }, - dangerRestrictedText: gettext("This group may not have dangerous permissions or subgroups.") - }; - self.groupEditorDialog = undefined; - self.groupsList.subscribe(function (oldValue) { - if (oldValue === undefined || oldValue.length === 0) - return; - oldValue.forEach(function (p) { - delete self[p.key.toUpperCase()]; - }); - }, null, "beforeChange"); - self.groupsList.subscribe(function (newValue) { - if (newValue === undefined) - return; - newValue.forEach(function (g) { - var needs = []; - g.permissions.forEach(function (p) { - for (var key in p.needs) { - p.needs[key].forEach(function (value) { - needs.push(access.permissions.need(key, value)); - }); - } - }); - if (needs.length > 0) { - self.registerGroup(g.key.toUpperCase(), needs); - } - }); - }); - self.registerGroup = function (name, group) { - Object.defineProperty(self, name, { - value: group, - enumerable: true, - configurable: true - }); - } - ; - self.currentGroup.subscribe(function (newValue) { - if (newValue === undefined) { - self.editor.key(undefined); - self.editor.name(undefined); - self.editor.description(undefined); - self.editor.permissions([]); - self.editor.subgroups([]); - self.editor.default(false); - self.editor.header(gettext("Add group")); - self.editor.new(true); - self.editor.confirm = self.confirmAddGroup; - } else { - self.editor.key(newValue.key); - self.editor.name(newValue.name); - self.editor.description(newValue.description); - self.editor.permissions(newValue.permissions.slice(0)); - self.editor.subgroups(newValue.subgroups.slice(0)); - self.editor.default(newValue.default); - self.editor.header(_.sprintf(gettext('Edit group "%(name)s"'), { - name: newValue.name - })); - self.editor.new(false); - self.editor.confirm = self.confirmEditGroup; - } - }); - self.requestData = function () { - return OctoPrint.access.groups.list().done(self.fromResponse); - } - ; - self.fromResponse = function (response) { - var lookup = {}; - var defaults = []; - _.each(response.groups, function (group) { - lookup[group.key] = group; - if (group.default) { - defaults.push(group.key); - } - }); - self.lookup = lookup; - self.defaults = defaults; - self.listHelper.updateItems(response.groups); - } - ; - self.showAddGroupDialog = function () { - self.currentGroup(undefined); - $('ul.nav-pills a[data-toggle="tab"]:first', self.groupEditorDialog).tab("show"); - self.groupEditorDialog.modal({ - minHeight: function () { - return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); - } - }).css({ - "margin-left": function () { - return -($(this).width() / 2); - } - }); - } - ; - self.confirmAddGroup = function () { - var group = { - key: self.editor.name().toLowerCase().replace(/[^a-z0-9_ ]/g, "").replace(/ /g, "_"), - name: self.editor.name(), - description: self.editor.description(), - permissions: self.editor.permissions(), - subgroups: self.editor.subgroups(), - default: self.editor.default() - }; - self.addGroup(group).done(function () { - self.currentGroup(undefined); - self.groupEditorDialog.modal("hide"); - }); - } - ; - self.showEditGroupDialog = function (group) { - if (!group.changeable) - return; - self.currentGroup(group); - $('ul.nav-pills a[data-toggle="tab"]:first', self.groupEditorDialog).tab("show"); - self.groupEditorDialog.modal({ - minHeight: function () { - return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); - } - }).css({ - "margin-left": function () { - return -($(this).width() / 2); - } - }); - } - ; - self.confirmEditGroup = function () { - var group = self.currentGroup(); - var data = { - key: group.key, - name: group.name, - description: self.editor.description(), - permissions: self.editor.permissions(), - subgroups: self.editor.subgroups(), - default: self.editor.default() - }; - self.updateGroup(data).done(function () { - self.currentGroup(undefined); - self.groupEditorDialog.modal("hide"); - }); - } - ; - self.onStartup = function () { - self.groupEditorDialog = $("#settings-groupsEditorDialog"); - } - ; - self.addGroup = function (group) { - if (!group) { - throw OctoPrint.InvalidArgumentError("group must be set"); - } - return OctoPrint.access.groups.add(group).done(self.fromResponse); - } - ; - self.removeGroup = function (group) { - if (!group) { - throw OctoPrint.InvalidArgumentError("group must be set"); - } - if (!group.removable) - return; - showConfirmationDialog({ - title: gettext("Are you sure?"), - message: _.sprintf(gettext('You are about to delete the group "%(name)s".'), { - name: group.name - }), - proceed: gettext("Delete"), - onproceed: function () { - OctoPrint.access.groups.delete(group.key).done(function (response) { - self.fromResponse(response); - access.users.requestData(); - }); - } - }); - } - ; - self.updateGroup = function (group) { - if (!group) { - throw OctoPrint.InvalidArgumentError("group must be set"); - } - return OctoPrint.access.groups.update(group).done(self.fromResponse); - } - ; - return self; - } - )(); - access.permissions = (function () { - var self = {}; - self.need = function (method, value) { - return { - method: method, - value: value - }; - } - ; - self.roleNeed = function (value) { - return self.need("role", value); - } - ; - self.permissionList = ko.observableArray([]); - self.lookup = {}; - var registeredPermissions = []; - var registerPermission = function (key, permission) { - Object.defineProperty(self, key, { - value: permission, - enumerable: true, - configurable: true - }); - registeredPermissions.push(key); - }; - var clearAllRegisteredPermissions = function () { - _.each(registeredPermissions, function (key) { - delete self[key]; - }); - registeredPermissions = []; - }; - self.initialize = function () { - clearAllRegisteredPermissions(); - var permissionList = []; - var lookup = {}; - _.each(PERMISSIONS, function (permission) { - var needs = []; - _.each(permission.needs, function (value, key) { - needs.push(self.need(key, value)); - }); - if (needs.length > 0) { - registerPermission(permission.key, needs); - } - if (!permission.combined) { - permissionList.push(permission); - } - lookup[permission.key] = permission; - }); - permissionList.sort(access.permissionComparator); - self.permissionList(permissionList); - self.lookup = lookup; - } - ; - return self; - } - )(); - access.groupComparator = function (a, b) { - var nameA = a.name ? a.name.toUpperCase() : ""; - var nameB = b.name ? b.name.toUpperCase() : ""; - if (nameA < nameB) { - return -1; - } else if (nameA > nameB) { - return 1; - } else { - return 0; - } - } - ; - access.permissionComparator = function (a, b) { - var nameA = a.name ? a.name.toUpperCase() : ""; - var nameB = b.name ? b.name.toUpperCase() : ""; - var pluginA = a.plugin || ""; - var pluginB = b.plugin || ""; - var compA = pluginA + ":" + nameA; - var compB = pluginB + ":" + nameB; - if (compA < compB) { - return -1; - } else if (compA > compB) { - return 1; - } else { - return 0; - } - } - ; - access.groupList = function (data) { - if (data.groups === undefined) - return ""; - var mappedGroups = _.filter(_.map(data.groups, function (g) { - return access.groups.lookup[g]; - }), function (g) { - return g !== undefined; - }); - mappedGroups.sort(access.groupComparator); - return _.map(mappedGroups, function (g) { - return g.name; - }).join(", "); - } - ; - access.subgroupList = function (data) { - if (data.subgroups === undefined) - return ""; - var mappedGroups = _.filter(_.map(data.subgroups, function (g) { - return access.groups.lookup[g]; - }), function (g) { - return g !== undefined; - }); - mappedGroups.sort(access.groupComparator); - return _.map(mappedGroups, function (g) { - return g.name; - }).join(", "); - } - ; - access.permissionList = function (data) { - if (!data || data.permissions === undefined) - return ""; - var mappedPermissions = _.filter(_.map(data.permissions, function (p) { - return access.permissions.lookup[p]; - }), function (p) { - return p !== undefined; - }); - mappedPermissions.sort(access.permissionComparator); - return _.map(mappedPermissions, function (p) { - return p.name; - }).join(", "); - } - ; - access.onStartup = function () { - access.groups.onStartup(); - access.users.onStartup(); - } - ; - access.onServerConnect = function () { - access.permissions.initialize(); - } - ; - access.onServerReconnect = function () { - access.permissions.initialize(); - } - ; - access.onUserPermissionsChanged = access.onUserLoggedIn = access.onUserLoggedOut = function (user) { - if (access.loginState.hasPermission(access.permissions.SETTINGS)) { - access.groups.requestData().done(function () { - access.users.requestData(); - }); - } - } - ; - } - OCTOPRINT_VIEWMODELS.push([AccessViewModel, ["loginStateViewModel"], []]); -}); \ No newline at end of file diff --git a/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 b/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 index cdd4f42..7e82281 100644 --- a/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 +++ b/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 @@ -24,7 +24,7 @@
-
+ -
+
{% include "tabs/tab-content.jinja2" %}
@@ -49,12 +49,17 @@ {% block script%} {% endblock %} \ No newline at end of file diff --git a/octoprint_CalibrationTools/templates/macros.jinja2 b/octoprint_CalibrationTools/templates/macros.jinja2 index 766ebb1..95db195 100644 --- a/octoprint_CalibrationTools/templates/macros.jinja2 +++ b/octoprint_CalibrationTools/templates/macros.jinja2 @@ -26,12 +26,12 @@ {% set max = max|default("") %} {% set unit = unit|trim|default("") %}
-
+
-
+
{% if unit != "" %} @@ -49,12 +49,12 @@ {% set max = max|default("") %} {% set unit = unit|trim|default("") %}
-
+
-
+
{{ _(label) }} diff --git a/octoprint_CalibrationTools/templates/tabs/tab-doc.jinja2 b/octoprint_CalibrationTools/templates/tabs/tab-doc.jinja2 index da9fa03..38278fd 100644 --- a/octoprint_CalibrationTools/templates/tabs/tab-doc.jinja2 +++ b/octoprint_CalibrationTools/templates/tabs/tab-doc.jinja2 @@ -1,3 +1,38 @@ {% import "macros.jinja2" as snipped %} -{{ snipped.quote("For using this plugin, I strongly recommending you to read teachingtechyt.github.io","", "text-warning") }} \ No newline at end of file +{{ snipped.quote("Before starting I strongly recommend reading some documentation about tunning teachingtechyt.github.io","", +"text-warning") }} +The stepper motors divides a full rotation in a number of equal steps. +E-Steps tuning is a process of setting the exact number of steps need it for pushing a fix amount of filament for feeding the hot-end.
+ +{{ snipped.subSection("E-Steps") }} +You will have to: + +
  • Mark a specific length of filament at the extruder motor entrance;
  • +
  • Set the hot-end on a printing temperature in E-Steps tab;
  • +
  • Set the extrusion length and speed;
  • +
  • Press "Start extrusion";
  • +
  • When extrusion finished, check the remaining length between the extruder and the filament mark location;
  • +
  • Refresh the current values from EEPROM;
  • +
  • Feed data collected in E-Steps tab and save the results in EEPROM;
  • +
    + +{{ snipped.subSection("X-Y-Z Steps") }} +You will have to: + +
  • Print a test cube with a known size on all three axes X,Y,X;
  • +
  • Refresh the current values from EEPROM;
  • +
  • Feed data collected in E-Steps tab and save the results in EEPROM;
  • +
    + + +{{ snipped.subSection("PID Autotune") }} +You will have to: + +
  • Refresh the current values from EEPROM;
  • +
  • Set the hot-end index which you want to tune;
  • +
  • Set the usual temperature used in your prints for that specific hot-end;
  • +
  • Set the usual fan speed used in your prints;
  • +
  • Monitor temperature tab, when it starts to cool down save the results in EEPROM;
  • +
  • For tuning heated bed the index is already set on -1;
  • +
    \ No newline at end of file diff --git a/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2 b/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2 index 60cb3d0..a55d901 100644 --- a/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2 +++ b/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2 @@ -1,24 +1,36 @@ {% import "macros.jinja2" as snipped %} {{ snipped.subSection("Process description", true) }} + +You will have to: + +
  • Mark a specific length of filament at the extruder motor entrance;
  • +
  • Set the hot-end on a printing temperature in E-Steps tab;
  • +
  • Set the extrusion length and speed;
  • +
  • Press "Start extrusion";
  • +
  • When extrusion finished, check the remaining length between the extruder and the filament mark location;
  • +
  • Refresh the current values from EEPROM;
  • +
  • Feed data collected in E-Steps tab and save the results in EEPROM;
  • +
    +
    + {{ snipped.quote(" This calibration is best done with the extruder detached from the hot end, so no restriction is present on the movement. If it is convenient, you can partially disassemble the printer so the output of the extruder is open and the filament exits in free air. If this is inconvenient, the process below aims to minimize restrictions by extruding very slowly and with a slightly higher temperature. The results from this should still be reliable. -", " -For more information about how to use this visit teachingtechyt.github.io -", "text-warning") }} +", "teachingtechyt.github.io", "text-warning") }} + +{{ snipped.subSection("Parameters", true) }} -{{ snipped.subSection("Test parameters") }}
    -
    +
    -
    +
    {{ snipped.linkToMarlin("M104", "Marlin website") }} M104   S @@ -29,12 +41,12 @@ reliable.
    -
    +
    -
    +
    {{ snipped.linkToMarlin("G000-G001", "Marlin website") }} G1   E @@ -49,8 +61,8 @@ reliable. {{ snipped.field("Extrusion marking length", "The length marked on filament before extrusion. ", "number", "$root.testParam.markLength", "true", "mm", 0.01, 50) }}
    -
    -
    +
    +
    -{{ snipped.subSection("Test results") }} +{{ snipped.subSection("Results") }}
    -
    +
    -
    +
    steps/mm @@ -85,12 +97,12 @@ reliable.
    -
    +
    -
    +
    {{ snipped.linkToMarlin("M092", "Marlin website") }} @@ -100,8 +112,8 @@ reliable.
    -
    -
    +
    +