Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
8b9b08f382 | |||
7612b7081c | |||
4df6a99238 | |||
acf3db65f6 | |||
18f009fa85 | |||
79bc20c81a | |||
05e2e10497 |
12
README.md
12
README.md
@ -1,10 +1,16 @@
|
||||
# OctoPrint-FanSpeedSlider
|
||||
# Fan Speed Slider Plugin
|
||||
|
||||
Adds a slider to control the speed of a parts cooling fan.
|
||||
Add a slider to control the speed of a parts cooling fan.
|
||||
|
||||

|
||||
|
||||
*Note: Slider does __not__ follow the speed of the fan. If the fan speed is set via gcode or an LCD panel on the printer, the slider will not respond to the change.*
|
||||
## Usage
|
||||
|
||||
Slide the slider, click the button. There really isn't much else to do :)
|
||||
|
||||
The default value of the slider is user configurable, this is the value that the slider will be set to upon loading OctoPrint's UI, and any time you refresh the page. The default value setting does __NOT__ limit the output of the fan, if you set the default value to 10% and set the fan to 100% it will still come on at 100%. To limit the min/max speed of your fan during a print, please see your slicer's documentation and settings.
|
||||
|
||||
*Note: Slider does __not__ follow the speed of the fan. If the fan speed is set via gcode or an LCD panel on the printer, the slider will not respond to the change. It is a __setting__, not an indicator, and functions the same way the feedrate and flowrate sliders do.*
|
||||
|
||||
## Setup
|
||||
|
||||
|
@ -4,16 +4,25 @@ from __future__ import absolute_import
|
||||
import octoprint.plugin
|
||||
|
||||
class FanSliderPlugin(octoprint.plugin.StartupPlugin,
|
||||
octoprint.plugin.TemplatePlugin,
|
||||
octoprint.plugin.SettingsPlugin,
|
||||
octoprint.plugin.AssetPlugin):
|
||||
|
||||
def get_assets(self):
|
||||
return dict(
|
||||
js=["js/fanslider.js"]
|
||||
)
|
||||
|
||||
def get_update_information(self):
|
||||
octoprint.plugin.TemplatePlugin,
|
||||
octoprint.plugin.SettingsPlugin,
|
||||
octoprint.plugin.AssetPlugin):
|
||||
|
||||
def get_settings_defaults(self):
|
||||
return dict(fanSpeed=100)
|
||||
|
||||
def get_assets(self):
|
||||
return dict(
|
||||
js=["js/fanslider.js"],
|
||||
css=["css/style.css"]
|
||||
)
|
||||
|
||||
def get_template_configs(self):
|
||||
return [
|
||||
dict(type="settings", custom_bindings=False)
|
||||
]
|
||||
|
||||
def get_update_information(self):
|
||||
return dict(
|
||||
fanspeedslider=dict(
|
||||
displayName="Fan Speed Slider",
|
||||
|
20
octoprint_fanspeedslider/static/css/style.css
Normal file
20
octoprint_fanspeedslider/static/css/style.css
Normal file
@ -0,0 +1,20 @@
|
||||
#touch body #control #control-fan-slider {
|
||||
padding: 30px 0 15px 15px;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
#touch body #control #control-fan-slider button, #touch body #control #control-fan-slider input {
|
||||
padding: 10px 20px;
|
||||
margin: 0 0 20px;
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
height: auto;
|
||||
-ms-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div#settings_plugin_fanspeedslider div {
|
||||
width: 80%;
|
||||
}
|
@ -1,49 +1,65 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Author: ntoff
|
||||
* License: AGPLv3
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
function FanSliderPluginViewModel(parameters) {
|
||||
function FanSliderPluginViewModel(parameters) {
|
||||
var self = this;
|
||||
|
||||
self.printerstate = parameters[0];
|
||||
self.loginstate = parameters[1];
|
||||
self.control = parameters[2]
|
||||
|
||||
fanSpeed = ko.observable(255);
|
||||
//convert 0 - 255 to 0 - 100% for the button
|
||||
fanPercent = ko.pureComputed(function () {
|
||||
return Math.floor(fanSpeed() /255 * 100);
|
||||
self.control = parameters[2];
|
||||
self.settings = parameters[3];
|
||||
|
||||
//default to 100% fan speed
|
||||
fanSpeed = ko.observable(undefined);
|
||||
//convert percentage into PWM
|
||||
fanPWM = ko.pureComputed(function () {
|
||||
return Math.round(fanSpeed() * 255 / 100);
|
||||
});
|
||||
//set fan speed
|
||||
//send gcode to set fan speed
|
||||
sendFanSpeed = function () {
|
||||
self.control.sendCustomCommand({ command: "M106 S" + fanSpeed() });
|
||||
};
|
||||
self.control.sendCustomCommand({ command: "M106 S" + fanPWM() });
|
||||
};
|
||||
//extra classes
|
||||
$("#control > div.jog-panel").eq(0).addClass("controls");
|
||||
$("#control > div.jog-panel").eq(1).addClass("tools");
|
||||
$("#control > div.jog-panel").eq(2).addClass("general");
|
||||
|
||||
//add ID to buttons
|
||||
$("#control > div.general").find("button").eq(0).attr("id", "motors-off");
|
||||
$("#control > div.general").find("button").eq(1).attr("id", "fan-on");
|
||||
$("#control > div.general").find("button").eq(2).attr("id", "fan-off");
|
||||
|
||||
//remove original fan on/off buttons
|
||||
$("#fan-on").remove();
|
||||
$("#fan-off").remove();
|
||||
//add new fan controls
|
||||
$("#control > div.jog-panel.general").find("button").eq(0).before("<input type=\"number\" style=\"width: 90px\" data-bind=\"slider: {min: 00, max: 255, step: 1, value: fanSpeed, tooltip: 'hide'}\">\
|
||||
<button class=\"btn btn-block control-box\" data-bind=\"enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { sendFanSpeed() }\">" + gettext("Fan on") + ":<span data-bind=\"text: fanPercent() + '%'\"></span></button>\
|
||||
<button class=\"btn btn-block control-box\" data-bind=\"enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendCustomCommand({ type: 'command', commands: ['M106 S0'] }) }\">" + gettext("Fan off") + "</button>");
|
||||
|
||||
$("#control > div.jog-panel").eq(2).addClass("general");
|
||||
//If !TouchUI then remove standard buttons + add slider + new buttons
|
||||
if ($("#touch body").length ==0 ) {
|
||||
//add ID to buttons
|
||||
$("#control > div.general").find("button").eq(0).attr("id", "motors-off");
|
||||
$("#control > div.general").find("button").eq(1).attr("id", "fan-on");
|
||||
$("#control > div.general").find("button").eq(2).attr("id", "fan-off");
|
||||
//remove original fan on/off buttons
|
||||
$("#fan-on").remove();
|
||||
$("#fan-off").remove();
|
||||
//add new fan controls
|
||||
$("#control > div.jog-panel.general").find("button").eq(0).before("\
|
||||
<input type=\"number\" style=\"width: 90px\" data-bind=\"slider: {min: 00, max: 100, step: 1, value: fanSpeed, tooltip: 'hide'}\">\
|
||||
<button class=\"btn btn-block control-box\" data-bind=\"enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { sendFanSpeed() }\">" + gettext("Fan on") + ":<span data-bind=\"text: fanSpeed() + '%'\"></span></button>\
|
||||
<button class=\"btn btn-block control-box\" data-bind=\"enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { $root.sendCustomCommand({ type: 'command', commands: ['M106 S0'] }) }\">" + gettext("Fan off") + "</button>\
|
||||
");
|
||||
} else { //if TouchUI is active we only add the speed input + fan on button in a new section.
|
||||
console.log("Fan Speed Slider: NOTICE! TouchUI is active, adding simplified control.");
|
||||
$("#control > div.jog-panel.general").after("\
|
||||
<div id=\"control-fan-slider\" class=\"jog-panel filament\" data-bind=\"visible: loginState.isUser\">\
|
||||
<div>\
|
||||
<input type=\"number\" style=\"width: 150px\" data-bind=\"slider: {min: 00, max: 255, step: 1, value: fanSpeed, tooltip: 'hide'}\">\
|
||||
<button class=\"btn btn-block control-box\" data-bind=\"enable: isOperational() && !isPrinting() && loginState.isUser(), click: function() { sendFanSpeed() }\">" + gettext("Fan Speed(%)") + "</button>\
|
||||
</div>\
|
||||
</div>\
|
||||
");
|
||||
}
|
||||
//retrieve settings
|
||||
self.onBeforeBinding = function() {
|
||||
fanSpeed(self.settings.settings.plugins.fanspeedslider.fanSpeed());
|
||||
}
|
||||
}
|
||||
OCTOPRINT_VIEWMODELS.push([
|
||||
FanSliderPluginViewModel,
|
||||
|
||||
["printerStateViewModel", "loginStateViewModel", "controlViewModel"]
|
||||
]);
|
||||
["printerStateViewModel", "loginStateViewModel", "controlViewModel", "settingsViewModel"]
|
||||
]);
|
||||
});
|
@ -0,0 +1,18 @@
|
||||
<h4>{{ _('Fan Speed Slider') }}</h4>
|
||||
<div>
|
||||
<p>{{ _('Set the default value for the fan speed slider.') }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<form class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Default Value') }}</label>
|
||||
<div class="controls">
|
||||
<div class="input-append">
|
||||
<input type="number" min="0" max="100" class="input-mini" data-bind="value: settings.plugins.fanspeedslider.fanSpeed">
|
||||
<span class="add-on">%</span>
|
||||
</div>
|
||||
<span class="help-inline">{{ _('This value does <i><b>not</b></i> affect the maximum or minimum speed of the fan. To limit the power the fan will use during a print, see your slicer\'s min / max fan speed setting.') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
2
setup.py
2
setup.py
@ -14,7 +14,7 @@ plugin_package = "octoprint_fanspeedslider"
|
||||
plugin_name = "OctoPrint-FanSpeedSlider"
|
||||
|
||||
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
|
||||
plugin_version = "0.1.0"
|
||||
plugin_version = "0.1.2"
|
||||
|
||||
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
|
||||
# module
|
||||
|
Reference in New Issue
Block a user