2017-08-28 23:10:51 +02:00
/ *
* Author : ntoff
* License : AGPLv3
* /
2017-11-11 21:33:51 +01:00
$ ( function ( ) {
2017-08-28 23:10:51 +02:00
2017-08-30 14:39:57 +02:00
function FanSliderPluginViewModel ( parameters ) {
2017-11-17 20:02:44 +01:00
//'use strict';
2017-08-28 23:10:51 +02:00
var self = this ;
2017-09-05 14:57:53 +02:00
self . settings = parameters [ 0 ] ;
self . control = parameters [ 1 ] ;
self . loginState = parameters [ 2 ] ;
2017-08-30 14:39:57 +02:00
2017-11-17 20:01:52 +01:00
self . settings . defaultFanSpeed = new ko . observable ( 100 ) ; //this,
self . control . fanSpeed = new ko . observable ( 100 ) ; //this,
self . settings . minFanSpeed = new ko . observable ( 0 ) ; //this,
self . settings . maxFanSpeed = new ko . observable ( 100 ) ; //and this are percents 0 - 100%
self . settings . notifyDelay = new ko . observable ( 4000 ) ; //time in milliseconds
2018-12-04 17:10:11 +01:00
self . settings . lockfan = new ko . observable ( false ) ; //ignore fan inputs from gcode and lock the fan buttons
2017-09-04 19:52:55 +02:00
2018-12-04 17:10:11 +01:00
//Not sure why I put these here, I swear I had a plan when I did it, something about dynamic text? I dunno, should move it back to the settings page
2017-11-17 23:00:16 +01:00
self . settings . commonTitle = ko . observable ( gettext ( "\n\nThis allows limiting the cooling fan without having to re-slice your model.\n\nLimited to prints controlled by OctoPrint." ) ) ;
self . settings . defaultTitle = ko . observable ( gettext ( "This is the value the slider will default to when the UI is loaded / refreshed." ) ) ;
self . settings . minTitle = ko . observable ( gettext ( "Set this to the lowest value at which your fan will spin." ) + self . settings . commonTitle ( ) ) ;
self . settings . maxTitle = ko . observable ( gettext ( "Set this <100% if your cooling fan is too strong on full." ) + self . settings . commonTitle ( ) ) ;
self . settings . noticeTitle = ko . observable ( gettext ( "Notifications only apply when setting the speed via the slider + button in the UI. Set to 0 (zero) to disable notifications." ) ) ;
2017-11-11 21:33:51 +01:00
self . showNotify = function ( self , options ) {
2017-11-11 16:02:29 +01:00
options . title = "Fan Speed Control" ;
2018-12-04 17:10:11 +01:00
options . delay = options . delay || self . settings . notifyDelay ( ) ;
options . type = options . type || "info" ;
2017-11-11 16:02:29 +01:00
if ( options . delay != "0" ) {
new PNotify ( options ) ;
}
2017-11-11 17:20:17 +01:00
} ;
2017-11-11 18:38:25 +01:00
2017-11-11 21:33:51 +01:00
self . control . fanSpeedToPwm = ko . pureComputed ( function ( ) {
2017-11-11 16:02:29 +01:00
self . speed = self . control . fanSpeed ( ) * 255 / 100 //don't forget to limit this to 2 decimal places at some point.
2017-11-11 21:33:51 +01:00
return self . speed ;
} ) ;
self . control . checkSliderValue = ko . pureComputed ( function ( ) {
2017-11-17 19:36:40 +01:00
if ( self . control . fanSpeed ( ) < self . settings . minFanSpeed ( ) && self . control . fanSpeed ( ) != "0" ) {
console . log ( "Fan Speed Control Plugin: " + self . control . fanSpeed ( ) + "% is less than the minimum speed (" + self . settings . minFanSpeed ( ) + "%), increasing." ) ;
self . control . fanSpeed ( self . settings . minFanSpeed ( ) ) ;
2017-11-11 16:02:29 +01:00
var options = {
2018-12-04 17:10:11 +01:00
hide : true ,
2017-11-17 19:36:40 +01:00
text : gettext ( 'Fan speed increased to meet minimum speed requirement.' ) ,
2017-11-12 07:26:38 +01:00
addclass : 'fan_speed_notice_low' ,
}
if ( $ ( ".fan_speed_notice_low" ) . length < 1 ) {
self . showNotify ( self , options ) ;
2017-11-11 16:02:29 +01:00
}
}
2017-11-17 19:36:40 +01:00
else if ( self . control . fanSpeed ( ) > self . settings . maxFanSpeed ( ) ) {
console . log ( "Fan Speed Control Plugin: " + self . control . fanSpeed ( ) + "% is more than the maximum speed (" + self . settings . maxFanSpeed ( ) + "%), decreasing." ) ;
self . control . fanSpeed ( self . settings . maxFanSpeed ( ) ) ;
2017-11-11 21:33:51 +01:00
var options = {
2018-12-04 17:10:11 +01:00
hide : true ,
2017-11-17 19:36:40 +01:00
text : gettext ( 'Fan speed decreased to meet maximum speed requirement.' ) ,
2017-11-12 07:26:38 +01:00
addclass : 'fan_speed_notice_high' ,
}
if ( $ ( ".fan_speed_notice_high" ) . length < 1 ) {
self . showNotify ( self , options ) ;
2017-11-11 21:33:51 +01:00
}
2017-11-11 16:02:29 +01:00
}
2017-08-28 23:10:51 +02:00
} ) ;
2017-11-11 18:38:25 +01:00
2017-11-11 21:33:51 +01:00
//send gcode to set fan speed
self . control . sendFanSpeed = function ( ) {
self . control . checkSliderValue ( ) ;
self . control . sendCustomCommand ( { command : "M106 S" + self . control . fanSpeedToPwm ( ) } ) ;
} ;
2018-12-04 17:10:11 +01:00
self . control . lockFanInput = function ( ) {
self . settings . settings . plugins . fanspeedslider . lockfan ( ! self . settings . settings . plugins . fanspeedslider . lockfan ( ) ) ;
self . settings . saveData ( ) ;
self . updateSettings ( ) ;
var options = {
type : "info" ,
hide : true ,
delay : 1000 * 60 ,
text : gettext ( 'CAUTION!! Fan speed commands are now being ignored! \n This includes commands sent via gcode and the terminal!' ) ,
addclass : 'fan_speed_notice_fanlocked' ,
}
if ( self . settings . lockfan ( ) && $ ( ".fan_speed_notice_fanlocked" ) . length < 1 ) {
self . showNotify ( self , options ) ;
}
}
//disables the on/off buttons if the lock is enabled
self . control . islocked = ko . pureComputed ( function ( ) {
return self . settings . settings . plugins . fanspeedslider . lockfan ( ) ;
} ) ;
2017-11-11 16:02:29 +01:00
//ph34r
2017-11-06 08:23:25 +01:00
try {
2017-11-11 18:38:25 +01:00
//for some reason touchui uses "jog general" for the fan controls? Oh well, makes my job easier
$ ( "#control-jog-general" ) . find ( "button" ) . eq ( 0 ) . attr ( "id" , "motors-off" ) ;
$ ( "#control-jog-general" ) . find ( "button" ) . eq ( 1 ) . attr ( "id" , "fan-on" ) ;
$ ( "#control-jog-general" ) . find ( "button" ) . eq ( 2 ) . attr ( "id" , "fan-off" ) ;
2017-11-11 16:02:29 +01:00
//If not TouchUI then remove standard buttons + add slider + new buttons
2017-11-11 21:33:51 +01:00
if ( $ ( "#touch body" ) . length == 0 ) {
2017-11-06 08:23:25 +01:00
//remove original fan on/off buttons
$ ( "#fan-on" ) . remove ( ) ;
$ ( "#fan-off" ) . remove ( ) ;
//add new fan controls
2017-11-11 17:20:17 +01:00
$ ( "#control-jog-general" ) . find ( "button" ) . eq ( 0 ) . before ( " \
2017-11-17 19:18:37 +01:00
< input type = \ "number\" style=\"width: 95px\" data-bind=\"slider: {min: 00, max: 100, step: 1, value: fanSpeed, tooltip: 'hide'}\" > \
2018-12-04 17:10:11 +01:00
< button class = \ "btn btn-block control-box\" id=\"fan-on\" data-bind=\"enable: isOperational() && loginState.isUser() && !islocked(), click: function() { $root.sendFanSpeed() }\">" + gettext ( "Fan speed" ) + ":<span data-bind=\"text: fanSpeed() + '%'\" > < / s p a n > < / b u t t o n > \
< div class = \ "btn-group\" > \
< button class = \ "btn \" id=\"fan-off\" data-bind=\"enable: isOperational() && loginState.isUser() && !islocked(), click: function() { $root.sendCustomCommand({ type: 'command', commands: ['M106 S0'] }) }\">" + gettext ( "Fan off" ) + " < / b u t t o n > \
< button class = \ "btn \" id=\"fan-off\" data-bind=\"enable: isOperational() && loginState.isUser(), click: function() { $root.lockFanInput() }\" title=\"" + gettext ( "Lock or unlock the fan controls. When locked, OctoPrint will NOT send ANY M106 / M107 commands to the printer, including those found in the gcode. Use with caution." ) + "\"><i class=\"fa fa-unlock\" data-bind=\"css: {'fa-lock': islocked(), 'fa-unlock': !islocked()}\" > < / i > < / b u t t o n > \
< / d i v > \
2017-11-06 08:23:25 +01:00
" ) ;
2017-11-11 21:33:51 +01:00
} else {
2017-11-11 18:38:25 +01:00
//replace touch UI's fan on button with one that sends whatever speed is set in this plugin
$ ( "#fan-on" ) . remove ( ) ;
$ ( "#control-jog-general" ) . find ( "button" ) . eq ( 0 ) . after ( " \
2017-11-11 19:46:00 +01:00
< button class = \ "btn btn-block control-box\" id=\"fan-on\" data-bind=\"enable: isOperational() && loginState.isUser(), click: function() { $root.sendFanSpeed() }\">" + gettext ( "Fan on" ) + " < / b u t t o n > \
2017-11-11 18:38:25 +01:00
" ) ;
//also add spin box + button below in its own section, button is redundant but convenient
2017-11-17 22:21:29 +01:00
$ ( "#control-jog-feedrate" ) . append ( " \
< input type = \ "number\" style=\"width: 150px\" data-bind=\"slider: {min: 00, max: 100, step: 1, value: fanSpeed, tooltip: 'hide'}\" > \
2018-12-04 17:10:11 +01:00
< button class = \ "btn btn-block\" style=\"width: 169px\" data-bind=\"enable: isOperational() && loginState.isUser() && !islocked(), click: function() { $root.sendFanSpeed() }\">" + gettext ( "Fan speed:" ) + "<span data-bind=\"text: fanSpeed() + '%'\" > < / s p a n > < / b u t t o n > \
< button class = \ "btn \" id=\"fan-off\" data-bind=\"enable: isOperational() && loginState.isUser(), click: function() { $root.lockFanInput() }\" title=\"" + gettext ( "Lock or unlock the fan controls. When locked, OctoPrint will NOT send ANY M106 / M107 commands to the printer, including those found in the gcode. Use with caution." ) + "\">" + gettext ( 'Fan Controls ' ) + "<i class=\"fa fa-unlock\" data-bind=\"css: {'fa-lock': islocked(), 'fa-unlock': !islocked()}\" > < / i > < / b u t t o n > \
" ) ;
2017-11-06 08:23:25 +01:00
}
}
2017-11-11 21:33:51 +01:00
catch ( error ) {
2017-11-06 08:23:25 +01:00
console . log ( error ) ;
2017-08-30 10:28:26 +02:00
}
2017-11-11 18:38:25 +01:00
2017-11-11 21:33:51 +01:00
self . updateSettings = function ( ) {
2017-11-11 18:38:25 +01:00
try {
2017-11-17 19:36:40 +01:00
self . settings . minFanSpeed ( parseInt ( self . settings . settings . plugins . fanspeedslider . minSpeed ( ) ) ) ;
self . settings . maxFanSpeed ( parseInt ( self . settings . settings . plugins . fanspeedslider . maxSpeed ( ) ) ) ;
self . settings . notifyDelay ( parseInt ( self . settings . settings . plugins . fanspeedslider . notifyDelay ( ) ) ) ;
2018-12-04 17:10:11 +01:00
self . settings . lockfan ( self . settings . settings . plugins . fanspeedslider . lockfan ( ) ) ;
2017-11-11 18:38:25 +01:00
}
2017-11-11 21:33:51 +01:00
catch ( error ) {
2017-11-11 18:38:25 +01:00
console . log ( error ) ;
}
}
2017-11-11 21:33:51 +01:00
self . onBeforeBinding = function ( ) {
2017-11-17 19:36:40 +01:00
self . settings . defaultFanSpeed ( parseInt ( self . settings . settings . plugins . fanspeedslider . defaultFanSpeed ( ) ) ) ;
2017-11-11 18:38:25 +01:00
self . updateSettings ( ) ;
//if the default fan speed is above or below max/min then set to either max or min
2017-11-17 19:36:40 +01:00
if ( self . settings . defaultFanSpeed ( ) < self . settings . minFanSpeed ( ) ) {
self . control . fanSpeed ( self . settings . minFanSpeed ( ) ) ;
2017-11-11 18:38:25 +01:00
}
2017-11-17 19:36:40 +01:00
else if ( self . settings . defaultFanSpeed ( ) > self . settings . maxFanSpeed ( ) ) {
self . control . fanSpeed ( self . settings . maxFanSpeed ( ) ) ;
2017-11-11 18:38:25 +01:00
}
2017-11-11 20:19:12 +01:00
else {
2017-11-17 19:36:40 +01:00
self . control . fanSpeed ( self . settings . defaultFanSpeed ( ) ) ;
2017-11-17 19:18:37 +01:00
}
2017-11-11 16:02:29 +01:00
}
2017-11-11 18:38:25 +01:00
2017-11-11 16:02:29 +01:00
//update settings in case user changes them, otherwise a refresh of the UI is required
2017-11-11 21:33:51 +01:00
self . onSettingsHidden = function ( ) {
2017-11-11 18:38:25 +01:00
self . updateSettings ( ) ;
2017-08-30 14:39:57 +02:00
}
2017-11-11 21:33:51 +01:00
}
2017-11-11 12:41:07 +01:00
OCTOPRINT _VIEWMODELS . push ( {
2017-11-11 17:20:17 +01:00
construct : FanSliderPluginViewModel ,
additionalNames : [ ] ,
dependencies : [ "settingsViewModel" , "controlViewModel" , "loginStateViewModel" ] ,
optional : [ ] ,
elements : [ ]
2017-11-11 16:02:29 +01:00
} ) ;
2017-11-11 12:41:07 +01:00
} ) ;