This commit is contained in:
de Miranda Henrique
2018-02-28 13:57:30 -06:00
parent 443b04efa8
commit 17b1a96d71
23 changed files with 1083 additions and 893 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
from neopixel import *
import sys
import time
LED_INVERT = False
LED_DMA = 5
LED_FREQ_HZ = 800000
if len(sys.argv) == 8:
LED_PIN = int(sys.argv[1])
LED_COUNT = int(sys.argv[2])
LED_BRIGHTNESS = int(sys.argv[3])
red = int(sys.argv[4])
green = int(sys.argv[5])
blue = int(sys.argv[6])
address = int(sys.argv[7], 16)
else:
print("fail")
sys.exit(1)
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT)
strip.begin()
color = Color(green, red, blue)
for i in range(LED_COUNT):
strip.setPixelColor(i, color)
strip.show()
print("ok")

0
octoprint_enclosure/static/css/bootstrap-colorpicker.css vendored Executable file → Normal file
View File

View File

@@ -1,85 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap2-toggle.css v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
label.checkbox .toggle,
label.checkbox.inline .toggle {
margin-left: -20px;
margin-right: 5px;
}
.toggle {
min-width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.toggle input[type="checkbox"] {
display: none;
}
.toggle-group {
position: absolute;
width: 200%;
top: 0;
bottom: 0;
left: 0;
transition: left 0.35s;
-webkit-transition: left 0.35s;
-moz-user-select: none;
-webkit-user-select: none;
}
.toggle.off .toggle-group {
left: -100%;
}
.toggle-on {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 50%;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-off {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
right: 0;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-handle {
position: relative;
margin: 0 auto;
padding-top: 0px;
padding-bottom: 0px;
height: 100%;
width: 0px;
border-width: 0 1px;
}
.toggle-handle.btn-mini {
top: -1px;
}
.toggle.btn { min-width: 30px; }
.toggle-on.btn { padding-right: 24px; }
.toggle-off.btn { padding-left: 24px; }
.toggle.btn-large { min-width: 40px; }
.toggle-on.btn-large { padding-right: 35px; }
.toggle-off.btn-large { padding-left: 35px; }
.toggle.btn-small { min-width: 25px; }
.toggle-on.btn-small { padding-right: 20px; }
.toggle-off.btn-small { padding-left: 20px; }
.toggle.btn-mini { min-width: 20px; }
.toggle-on.btn-mini { padding-right: 12px; }
.toggle-off.btn-mini { padding-left: 12px; }

View File

@@ -30,8 +30,8 @@
width: 15%;
}
#enclosure-table th.temperature_control,
#enclosure-table td.temperature_control {
#enclosure-table th.temp_hum_control,
#enclosure-table td.temp_hum_control {
width: 15%;
}
@@ -51,4 +51,24 @@
text-shadow: 4px 4px 15px red;
}
.enclosure-link{
text-decoration: none;
}
.enclosure-link:hover{
text-decoration: none;
}
.navbar-enclosure{
text-shadow: 0 1px 0 #ccc;
color: #333;
float: none;
padding: 10px 15px 10px;
text-decoration: none;
}
.neopixel-div{
width: 25%;
}

View File

Before

Width:  |  Height:  |  Size: 557 B

After

Width:  |  Height:  |  Size: 557 B

View File

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 488 B

View File

Before

Width:  |  Height:  |  Size: 478 B

After

Width:  |  Height:  |  Size: 478 B

View File

Before

Width:  |  Height:  |  Size: 504 B

After

Width:  |  Height:  |  Size: 504 B

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

0
octoprint_enclosure/static/js/bootstrap-colorpicker.min.js vendored Executable file → Normal file
View File

View File

@@ -1,180 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap2-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
+function ($) {
'use strict';
// TOGGLE PUBLIC CLASS DEFINITION
// ==============================
var Toggle = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, this.defaults(), options)
this.render()
}
Toggle.VERSION = '2.2.0'
Toggle.DEFAULTS = {
on: 'On',
off: 'Off',
onstyle: 'primary',
offstyle: 'default',
size: 'normal',
style: '',
width: null,
height: null
}
Toggle.prototype.defaults = function() {
return {
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
}
}
Toggle.prototype.render = function () {
this._onstyle = 'btn-' + this.options.onstyle
this._offstyle = 'btn-' + this.options.offstyle
var size = this.options.size === 'large' ? 'btn-large'
: this.options.size === 'small' ? 'btn-small'
: this.options.size === 'mini' ? 'btn-mini'
: ''
var $toggleOn = $('<label class="btn">').html(this.options.on)
.addClass(this._onstyle + ' ' + size)
var $toggleOff = $('<label class="btn">').html(this.options.off)
.addClass(this._offstyle + ' ' + size + ' active')
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
.addClass(size)
var $toggleGroup = $('<div class="toggle-group">')
.append($toggleOn, $toggleOff, $toggleHandle)
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
.addClass(size).addClass(this.options.style)
this.$element.wrap($toggle)
$.extend(this, {
$toggle: this.$element.parent(),
$toggleOn: $toggleOn,
$toggleOff: $toggleOff,
$toggleGroup: $toggleGroup
})
this.$toggle.append($toggleGroup)
var width = this.options.width || Math.max($toggleOn.width(), $toggleOff.width())+($toggleHandle.outerWidth()/2)
var height = this.options.height || Math.max($toggleOn.height(), $toggleOff.height())
$toggleOn.addClass('toggle-on')
$toggleOff.addClass('toggle-off')
this.$toggle.css({ width: width, height: height })
if (this.options.height) {
$toggleOn.css('line-height', $toggleOn.height() + 'px')
$toggleOff.css('line-height', $toggleOff.height() + 'px')
}
this.update(true)
this.trigger(true)
}
Toggle.prototype.toggle = function () {
if (this.$element.prop('checked')) this.off()
else this.on()
}
Toggle.prototype.on = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
this.$element.prop('checked', true)
if (!silent) this.trigger()
}
Toggle.prototype.off = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
this.$element.prop('checked', false)
if (!silent) this.trigger()
}
Toggle.prototype.enable = function () {
this.$toggle.removeAttr('disabled')
this.$element.prop('disabled', false)
}
Toggle.prototype.disable = function () {
this.$toggle.attr('disabled', 'disabled')
this.$element.prop('disabled', true)
}
Toggle.prototype.update = function (silent) {
if (this.$element.prop('disabled')) this.disable()
else this.enable()
if (this.$element.prop('checked')) this.on(silent)
else this.off(silent)
}
Toggle.prototype.trigger = function (silent) {
this.$element.off('change.bs.toggle')
if (!silent) this.$element.change()
this.$element.on('change.bs.toggle', $.proxy(function() {
this.update()
}, this))
}
Toggle.prototype.destroy = function() {
this.$element.off('change.bs.toggle')
this.$toggleGroup.remove()
this.$element.removeData('bs.toggle')
this.$element.unwrap()
}
// TOGGLE PLUGIN DEFINITION
// ========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.toggle')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
if (typeof option == 'string' && data[option]) data[option]()
})
}
var old = $.fn.bootstrapToggle
$.fn.bootstrapToggle = Plugin
$.fn.bootstrapToggle.Constructor = Toggle
// TOGGLE NO CONFLICT
// ==================
$.fn.toggle.noConflict = function () {
$.fn.bootstrapToggle = old
return this
}
// TOGGLE DATA-API
// ===============
$(function() {
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
})
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
var $checkbox = $(this).find('input[type=checkbox]')
$checkbox.bootstrapToggle('toggle')
e.preventDefault()
})
}(jQuery);

View File

@@ -11,21 +11,15 @@ $(function () {
self.rpi_outputs = ko.observableArray();
self.rpi_inputs = ko.observableArray();
self.rpi_outputs_regular = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (item.output_type() === "regular");
self.settings_outputs_regular = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs(), function (item) {
return (item.output_type() === "regular" && !item.toggle_timer());
});
});
self.rpi_possible_outputs = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (item.output_type() === "regular" || item.output_type() === "gcode_output");
});
});
self.rpi_outputs_pwm = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (item.output_type() === "pwm");
self.settings_possible_outputs = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs(), function (item) {
return ((item.output_type() === "regular" && !item.toggle_timer()) || item.output_type() === "gcode_output");
});
});
@@ -35,6 +29,18 @@ $(function () {
});
});
self.settings_temperature_sensors = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_inputs(), function (item) {
return (item.input_type() === "temperature_sensor");
});
});
self.settings_hum_sensors = ko.pureComputed(function () {
return ko.utils.arrayFilter(self.settings_temperature_sensors(), function (sensor) {
return (self.humidityCapableSensor(sensor.temp_sensor_type()));
});
});
self.debug = ko.observable();
self.debug_temperature_log = ko.observable();
self.filament_sensor_gcode = ko.observable();
@@ -50,11 +56,22 @@ $(function () {
return false;
};
self.isRegularOutput = function(index_id){
return_value = false;
self.settingsViewModel.settings.plugins.enclosure.rpi_outputs().forEach(function (output) {
if (output.index_id() == index_id && item.output_type() == "regular") {
return_value = true;
return false;
}
});
return return_value;
};
self.linkedTemperatureControl = function(sensor_index){
return ko.pureComputed(function () {
return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs(), function (item) {
return ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
if (item.linked_temp_sensor){
return (item.linked_temp_sensor() == sensor_index && item.output_type() == "temperature_control");
return (item.linked_temp_sensor() == sensor_index && item.output_type() == "temp_hum_control");
}else{
return false;
}
@@ -73,10 +90,32 @@ $(function () {
return return_value;
};
self.hasAnyNavbarOutput = function(){
return_value = false;
self.rpi_outputs().forEach(function (output) {
if ((output.output_type()=="regular" || output.output_type()=="gcode_output") && output.show_on_navbar()) {
return_value = true;
return false;
}
});
return return_value;
};
self.hasAnyNavbarTemperature = function(){
return_value = false;
self.rpi_inputs_temperature_sensors().forEach(function (sensor) {
if (sensor.temp_sensor_navbar()) {
return_value = true;
return false;
}
});
return return_value;
};
self.hasAnyTemperatureControl = function(){
return_value = false
self.rpi_outputs().forEach(function (output) {
if (output.output_type()=="temperature_control") {
if (output.output_type()=="temp_hum_control") {
return_value = true
return false;
}
@@ -112,56 +151,72 @@ $(function () {
return (set_temperature['index_id'] == temp_control.index_id());
}).pop();
if (linked_temp_control) {
linked_temp_control.temp_ctr_set_temp(set_temperature['set_temperature'])
linked_temp_control.temp_ctr_set_value(set_temperature['set_temperature'])
}
})
}
if (data.hasOwnProperty("rpi_output")) {
data.rpi_output.forEach(function (output) {
if (data.hasOwnProperty("rpi_output_regular")) {
data.rpi_output_regular.forEach(function (output) {
var linked_output = ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (output['index_id'] == item.index_id());
}).pop();
if (linked_output) {
linked_output.gpio_status(output['status'])
linked_output.auto_shutdown(output['auto_shutdown'])
linked_output.auto_startup(output['auto_startup'])
}
})
}
// if (!data.rpi_output) {
// data.rpi_output = self.previous_gpio_status;
// }
if (data.hasOwnProperty("rpi_output_temp_hum_ctrl")) {
data.rpi_output_temp_hum_ctrl.forEach(function (output) {
var linked_output = ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (output['index_id'] == item.index_id());
}).pop();
if (linked_output) {
linked_output.auto_shutdown(output['auto_shutdown'])
linked_output.auto_startup(output['auto_startup'])
}
})
}
// if (!data.rpi_output_pwm) {
// data.rpi_output_pwm = self.previous_gpio_pwm_status;
// }
if (data.hasOwnProperty("rpi_output_pwm")) {
data.rpi_output_pwm.forEach(function (output) {
var linked_output = ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (output['index_id'] == item.index_id());
}).pop();
if (linked_output) {
linked_output.duty_cycle(output['pwm_value'])
linked_output.auto_shutdown(output['auto_shutdown'])
linked_output.auto_startup(output['auto_startup'])
}
})
}
// if (data.rpi_output) {
// data.rpi_output.forEach(function (gpio) {
// key = Object.keys(gpio)[0];
// if (gpio[key]) {
// $("#btn_off_" + key).removeClass('active');
// $("#btn_on_" + key).addClass('active');
// } else {
// $("#btn_off_" + key).addClass('active');
// $("#btn_on_" + key).removeClass('active');
// }
// });
// self.previous_gpio_status = data.rpi_output;
// }
if (data.hasOwnProperty("rpi_output_neopixel")) {
data.rpi_output_neopixel.forEach(function (output) {
var linked_output = ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (output['index_id'] == item.index_id());
}).pop();
if (linked_output) {
linked_output.neopixel_color(output['color'])
linked_output.auto_shutdown(output['auto_shutdown'])
linked_output.auto_startup(output['auto_startup'])
}
})
}
// if (data.rpi_output_pwm) {
// data.rpi_output_pwm.forEach(function (gpio) {
// key = Object.keys(gpio)[0];
// val = gpio[key];
// if (parseFloat(val) != 100) {
// $("#duty_cycle_" + key).attr("placeholder", val);
// } else {
// $("#duty_cycle_" + key).attr("placeholder", "off");
// }
// });
// self.previous_gpio_pwm_status = data.rpi_output_pwm;
// }
if (data.hasOwnProperty("filament_sensor_status")) {
data.filament_sensor_status.forEach(function (filament_sensor) {
var linked_filament_sensor = ko.utils.arrayFilter(self.rpi_inputs(), function (item) {
return (filament_sensor['index_id'] == item.index_id());
}).pop();
if (linked_filament_sensor) {
linked_filament_sensor.filament_sensor_enabled(filament_sensor['filament_sensor_enabled'])
}
})
}
if (data.isMsg) {
new PNotify({
@@ -172,11 +227,14 @@ $(function () {
}
};
self.enableBtn = ko.computed(function () {
// return self.connectionViewModel.loginState.isUser() && self.printerStateViewModel.isOperational();
self.isUser = ko.computed(function () {
return self.connectionViewModel.loginState.isUser();
});
self.isOperational = ko.computed(function () {
return self.connectionViewModel.loginState.isUser() && self.printerStateViewModel.isOperational();
});
self.getCleanTemperature = function (temp) {
if (temp === undefined || isNaN(parseFloat(temp))) return "-";
@@ -184,6 +242,12 @@ $(function () {
return temp;
}
self.getDutyCycle = function (duty_cycle) {
if (duty_cycle === undefined || isNaN(parseFloat(duty_cycle))) return "-";
if (parseInt(duty_cycle) == 0) return String("off");
return duty_cycle;
}
self.bindSettings = function(){
self.rpi_outputs(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs());
self.rpi_inputs(self.settingsViewModel.settings.plugins.enclosure.rpi_inputs());
@@ -198,25 +262,13 @@ $(function () {
self.onBeforeBinding = function () {
self.bindSettings();
};
// self.settings = self.settingsViewModel.settings.plugins.enclosure;
// self.temperature_reading(self.settings.temperature_reading());
// // self.temperature_control(self.settings.temperature_control.slice(0));
self.onSettingsBeforeSave = function() {
self.bindSettings();
};
self.onStartupComplete = function () {
// self.requestEnclosureSetTemperature();
// $(".toggle").bootstrapToggle();
// self.requestEnclosureTemperature();
};
self.onDataUpdaterReconnect = function () {
// self.getUpdateBtnStatus();
};
self.onSettingsShown = function () {
};
@@ -227,19 +279,18 @@ $(function () {
}
self.onSettingsHidden = function () {
self.bindSettings();
// self.requestEnclosureTemperature();
self.showColorPicker();
};
self.getRegularOutputs = function () {
return self.settingsViewModel.settings.plugins.enclosure.rpi_outputs().filter(function (rpi_outputs) {
return self.rpi_outputs().filter(function (rpi_outputs) {
return rpi_outputs.output_type == 'regular';
});
};
self.setTemperature = function (item, form) {
var newSetTemperature = item.temp_ctr_new_set_temp();
var newSetTemperature = item.temp_ctr_new_set_value();
if (form !== undefined) {
$(form).find("input").blur();
}
@@ -248,13 +299,13 @@ $(function () {
var request = {set_temperature:newSetTemperature, index_id:item.index_id()};
$.ajax({
url: self.buildPluginUrl("/setEnclosureTemperature"),
url: self.buildPluginUrl("/setEnclosureTempHum"),
type: "GET",
dataType: "json",
data: request,
success: function (data) {
item.temp_ctr_new_set_temp("");
item.temp_ctr_set_temp(newSetTemperature);
item.temp_ctr_new_set_value("");
item.temp_ctr_set_value(newSetTemperature);
self.getUpdateUI();
},
error: function (textStatus, errorThrown) {
@@ -288,6 +339,9 @@ $(function () {
gpio_status: ko.observable(false),
hide_btn_ui: ko.observable(false),
active_low: ko.observable(true),
toggle_timer: ko.observable(false),
toggle_timer_on: ko.observable(0),
toggle_timer_off: ko.observable(0),
auto_startup: ko.observable(false),
controlled_io: ko.observable(0),
controlled_io_set_value: ko.observable("Low"),
@@ -298,29 +352,28 @@ $(function () {
alarm_set_temp: ko.observable(0),
temp_ctr_type: ko.observable("heater"),
temp_ctr_deadband: ko.observable(0),
temp_ctr_set_temp: ko.observable(0),
temp_ctr_new_set_temp: ko.observable(""),
temp_ctr_set_value: ko.observable(0),
temp_ctr_new_set_value: ko.observable(""),
temp_ctr_default_temp: ko.observable(0),
temp_ctr_max_temp: ko.observable(0),
pwm_frequency: ko.observable(50),
pwm_status: ko.observable(50),
duty_cycle: ko.observable(0),
neopixel_color: ko.observable("rgb(255,0,0)"),
default_duty_cycle: ko.observable(0),
new_duty_cycle: ko.observable(""),
neopixel_color: ko.observable("rgb(0,0,0)"),
new_neopixel_color: ko.observable(""),
neopixel_count: ko.observable(0),
neopixel_brightness: ko.observable(255),
microcontroller_address: ko.observable(0),
gcode: ko.observable("")
gcode: ko.observable(""),
show_on_navbar: ko.observable(false)
});
// var test = self.settingsViewModel.settings.plugins.enclosure.rpi_outputs();
// console.log(self.rpi_outputs_regular());
self.bindSettings();
};
self.removeRpiOutput = function (data) {
self.settingsViewModel.settings.plugins.enclosure.rpi_outputs.remove(data);
self.bindSettings();
};
self.addRpiInput = function () {
@@ -350,19 +403,16 @@ $(function () {
filament_sensor_timeout: ko.observable(120),
filament_sensor_enabled: ko.observable(true)
});
self.bindSettings();
};
self.removeRpiInput = function (definition) {
self.settingsViewModel.settings.plugins.enclosure.rpi_inputs.remove(definition);
self.bindSettings();
};
self.turnOffHeater = function (item) {
var request = { set_temperature: 0, index_id: item.index_id() };
$.ajax({
url: self.buildPluginUrl("/setEnclosureTemperature"),
url: self.buildPluginUrl("/setEnclosureTempHum"),
type: "GET",
dataType: "json",
data: request,
@@ -394,28 +444,6 @@ $(function () {
});
};
// self.requestEnclosureTemperature = function () {
// console.log("Requesting enclosure temperature");
// return $.ajax({
// type: "GET",
// url: self.buildPluginUrl("/getEnclosureTemperature"),
// async: false
// }).responseText;
// };
// self.requestEnclosureSetTemperature = function () {
// $.ajax({
// url: self.buildPluginUrl("/getEnclosureSetTemperature"),
// type: "GET",
// error: function (textStatus, errorThrown) {
// new PNotify({
// title: "Enclosure",
// text: "Error geting set temperatures",
// type: "error"
// });
// }});
// };
self.handleIO = function (item, form) {
var request = {
@@ -434,41 +462,107 @@ $(function () {
});
};
self.handlePWM = function (data, event) {
io = parseInt(data[0]);
pwmVal = parseInt($("#duty_cycle_" + io).val());
if (pwmVal < 0 || pwmVal > 100 || isNaN(pwmVal)) {
$("#duty_cycle_" + io).val('')
self.handleGcode = function (item, form) {
var request = {
"index_id": item.index_id()
};
$.ajax({
type: "GET",
dataType: "json",
data: request,
url: self.buildPluginUrl("/sendGcodeCommand")
});
};
self.switchAutoStartUp = function (item) {
var request = {
"status": !item.auto_startup(),
"index_id": item.index_id()
};
$.ajax({
type: "GET",
dataType: "json",
data: request,
url: self.buildPluginUrl("/setAutoStartUp"),
success: function (data) {
self.getUpdateUI();
}
});
};
self.switchAutoShutdown = function (item) {
var request = {
"status": !item.auto_shutdown(),
"index_id": item.index_id()
};
$.ajax({
type: "GET",
dataType: "json",
data: request,
url: self.buildPluginUrl("/setAutoShutdown"),
success: function (data) {
self.getUpdateUI();
}
});
};
self.switchFilamentSensor = function (item) {
var request = {
"status": !item.filament_sensor_enabled(),
"index_id": item.index_id()
};
$.ajax({
type: "GET",
dataType: "json",
data: request,
url: self.buildPluginUrl("/setFilamentSensor"),
success: function (data) {
self.getUpdateUI();
}
});
};
self.handlePWM = function (item) {
var pwm_value = item.new_duty_cycle();
pwm_value = parseInt(pwm_value);
if (pwm_value < 0 || pwm_value > 100 || isNaN(pwm_value)) {
item.new_duty_cycle("")
new PNotify({
title: "Enclosure",
text: "Duty Cycle value needs to be between 0 and 100!",
type: "error"
});
} else {
// console.log(pwmVal);
$("#duty_cycle_" + io).val('')
$("#duty_cycle_" + io).attr("placeholder", pwmVal);
var request = { new_duty_cycle: pwm_value, index_id: item.index_id() };
$.ajax({
type: "GET",
dataType: "json",
data: {
"io": io,
"pwmVal": pwmVal
},
data: request,
url: self.buildPluginUrl("/setPWM"),
success: function (data) {
item.new_duty_cycle("");
item.duty_cycle(pwm_value);
self.getUpdateUI();
}
});
}
};
self.handleNeopixel = function (data, event) {
io = parseInt(data[0]);
tempStr = ($("#color_" + io).val()).replace("rgb(", "");
self.handleNeopixel = function (item) {
r = parseInt(tempStr.substring(0, tempStr.indexOf(",")));
var index = item.index_id() ;
var or_tempStr = item.new_neopixel_color();
var tempStr = or_tempStr.replace("rgb(", "");
var r = parseInt(tempStr.substring(0, tempStr.indexOf(",")));
tempStr = tempStr.slice(tempStr.indexOf(",") + 1);
g = parseInt(tempStr.substring(0, tempStr.indexOf(",")));
var g = parseInt(tempStr.substring(0, tempStr.indexOf(",")));
tempStr = tempStr.slice(tempStr.indexOf(",") + 1);
b = parseInt(tempStr.substring(0, tempStr.indexOf(")")));
var b = parseInt(tempStr.substring(0, tempStr.indexOf(")")));
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || isNaN(r) || isNaN(g) || isNaN(b)) {
new PNotify({
@@ -481,12 +575,16 @@ $(function () {
type: "GET",
dataType: "json",
data: {
"io": io,
"index_id": index,
"red": r,
"green": g,
"blue": b
},
url: self.buildPluginUrl("/setNeopixel"),
success: function (data) {
item.new_neopixel_color("");
self.getUpdateUI();
}
});
}
};
@@ -505,7 +603,7 @@ $(function () {
// ViewModels your plugin depends on, e.g. loginStateViewModel, settingsViewModel, ...
dependencies: ["settingsViewModel", "connectionViewModel", "printerStateViewModel"],
// Elements to bind to, e.g. #settings_plugin_tasmota-mqtt, #tab_plugin_tasmota-mqtt, ...
elements: ["#tab_plugin_enclosure", "#settings_plugin_enclosure", "#navbar_plugin_enclosure"]
elements: ["#tab_plugin_enclosure", "#settings_plugin_enclosure", "#navbar_plugin_enclosure_1", "#navbar_plugin_enclosure_2"]
});
});

View File

@@ -0,0 +1,41 @@
<!-- ko if: ($root.hasAnyNavbarOutput() && $root.isUser()) -->
<a href="javascript:void(0)" title="Raspberry Pi Outputs" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-codepen"></i>
<b class="caret"></b>
</a>
<ul class="dropdown-menu" data-bind="foreach: $root.rpi_outputs()">
<!-- ko if: ($data.output_type() == "regular") -->
<li>
<a href="javascript:void(0)" data-bind="click: $root.handleIO">
<span data-bind="html: label"> </span>
<!-- ko if: ($data.gpio_status()) -->
<span class="badge badge-success help-inline">on</span>
<!-- /ko -->
<!-- ko ifnot: ($data.gpio_status()) -->
<span class="badge badge-important help-inline">off</span>
<!-- /ko -->
</a>
</li>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "gcode_output") -->
<!-- ko if: ($root.isOperational()) -->
<li>
<a href="javascript:void(0)" data-bind="click: $root.handleGcode">
<span data-bind="html: label"> </span>
<span class="badge badge-info">gcode</span>
</a>
</li>
<!-- /ko -->
<!-- ko ifnot: ($root.isOperational()) -->
<li>
<a href="javascript:void(0)">
<span data-bind="html: label"> </span>
<span class="badge">gcode</span>
</a>
</li>
<!-- /ko -->
<!-- /ko -->
</ul>
<!-- /ko -->

View File

@@ -0,0 +1,33 @@
<!-- ko if: ($root.hasAnyNavbarTemperature() && $root.isUser()) -->
<a href="javascript:void(0)" title="Regular Outputs" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-fire"></i>
<b class="caret"></b>
</a>
<ul class="dropdown-menu" data-bind="foreach: $root.rpi_inputs_temperature_sensors()">
<li>
<a href="javascript:void(0)">
<span data-bind="html: label"> </span>
</a>
</li>
<li>
<a href="javascript:void(0)">
<span data-bind="text: temp_sensor_temp, attr: {title: temp_sensor_temp}"> </span>
<!-- ko if: (use_fahrenheit()) -->
<span class="add-on">&deg;F</span>
<!-- /ko -->
<!-- ko ifnot: (use_fahrenheit()) -->
<span class="add-on">&deg;C</span>
<!-- /ko -->
</a>
</li>
<!-- ko if: ($root.humidityCapableSensor(temp_sensor_type())) -->
<li>
<a href="javascript:void(0)">
<span data-bind="text: temp_sensor_humidity, attr: {title: temp_sensor_humidity}"> </span>
<span class="add-on">%</span>
</a>
</li>
<!-- /ko -->
</ul>
<!-- /ko -->

View File

@@ -37,7 +37,7 @@
</div>
<div class="controls">
<label class="radio">
<input type="radio" value="temperature_control" data-bind="checked: output_type, attr: {name: 'output_type_' + $index() }"> {{ _('Temperature Control') }}
<input type="radio" value="temp_hum_control" data-bind="checked: output_type, attr: {name: 'output_type_' + $index() }"> {{ _('Temperature / Humidity Control') }}
</span>
</label>
</div>
@@ -66,7 +66,7 @@
<div class="control-group">
<label class="control-label">{{ _('Id') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: index_id" disabled="true">
<input type="text" class="input-block-level" data-bind="value: index_id" disabled="true">
<span class="help-inline">Id used for API control</span>
</div>
</div>
@@ -88,19 +88,38 @@
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "gcode_output" ) -->
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "pwm" ) -->
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: hide_btn_ui"> {{ _('Hide UI Button') }}
<input type="checkbox" data-bind="checked: toggle_timer"> {{ _('Timer Toggle') }}
</label>
<span class="help-inline">If you plan to use a physical button (INPUT) and want to hide the button from enclosure tab check this.</span>
<span class="help-inline">Toggle output every amount of secconds. It will start when the print starts and stop when print is complete.
For PWM pins it will use the default PWM value when ON.
</span>
</div>
</div>
<!-- ko if: ($data.toggle_timer()) -->
<div class="control-group">
<label class="control-label">{{ _('Time Toggle On') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: toggle_timer_on">
<span class="help-inline">Time delay in secconds that the GPIO will remain ON</span>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Time Toggle OFF') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: toggle_timer_off">
<span class="help-inline">Time delay in secconds that the GPIO will remain when OFF</span>
</div>
</div>
<!-- /ko -->
<!-- /ko -->
<!-- ko ifnot: (($data.output_type() == "regular" || $data.output_type() == "pwm") && $data.toggle_timer()) -->
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" ) -->
<div class="control-group">
<div class="controls">
@@ -145,7 +164,10 @@
</div>
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "temperature_control") -->
<!-- /ko -->
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "temp_hum_control") -->
<div class="control-group">
<div class="controls">
<label class="checkbox">
@@ -155,18 +177,54 @@
</div>
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "temperature_alarm" || $data.output_type() == "temperature_control") -->
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "gcode_output" ) -->
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: hide_btn_ui"> {{ _('Hide UI Button') }}
</label>
<span class="help-inline">If you plan to use a physical button (INPUT) and want to hide the button from enclosure tab check this.</span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: show_on_navbar"> {{ _('Show Button on Navbar') }}
</label>
<span class="help-inline">Add shortcut on navbar to toggle output</span>
</div>
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "temperature_alarm" || $data.output_type() == "temp_hum_control") -->
<!-- ko if: ($data.temp_ctr_type() == "heater" || $data.output_type() == "cooler") -->
<div class="control-group">
<label class="control-label">Temperature Sensor</label>
<div class="controls">
<select data-bind="options: $root.rpi_inputs_temperature_sensors, optionsText: 'label',
<select data-bind="options: $root.settings_temperature_sensors, optionsText: 'label',
optionsValue: 'index_id', value: $data.linked_temp_sensor">
</select>
<span class="help-inline">Temperature sensor responsible for geting the value to be used. Configured on the input side of the plugin.</span>
</div>
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "temperature_control") -->
<!-- ko if: ($data.temp_ctr_type() == "dehumidifier") -->
<div class="control-group">
<label class="control-label">Temperature Sensor</label>
<div class="controls">
<select data-bind="options: $root.settings_hum_sensors, optionsText: 'label',
optionsValue: 'index_id', value: $data.linked_temp_sensor">
</select>
<span class="help-inline">Temperature sensor responsible for geting the value to be used. Configured on the input side of the plugin.</span>
</div>
</div>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: ($data.output_type() == "temp_hum_control") -->
<div class="control-group">
<label class="control-label">{{ _('Temp Control Type') }}</label>
<div class="controls">
@@ -177,7 +235,13 @@
<label class="radio">
<input type="radio" value="cooler" name="optradio" data-bind="checked: temp_ctr_type"> {{ _('Cooler') }}</label>
</div>
<div class="controls">
<label class="radio">
<input type="radio" value="dehumidifier" name="optradio" data-bind="checked: temp_ctr_type"> {{ _('Dehumidifier') }}</label>
</div>
</div>
<!-- ko if: ($data.temp_ctr_type() == "heater" || $data.temp_ctr_type() == "cooler") -->
<div class="control-group">
<label class="control-label">{{ _('Default Temperature') }}</label>
<div class="controls">
@@ -192,12 +256,15 @@
<span class="help-inline">Allowabe drift on temperature control. Set it to zero to disable.</span>
</div>
</div>
<!-- /ko -->
<!-- ko if: ($data.temp_ctr_type() == "heater") -->
<div class="control-group">
<label class="control-label">{{ _('Maximum Temperature') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: temp_ctr_max_temp">
<span class="help-inline">Maximun temperature that the enclosure should reach, if this temperature is hit, the heater will be disabled until it's set temperature is set again.</span>
<span class="help-inline">Maximun temperature that the enclosure should reach, if this temperature is hit, the heater will be disabled until
it's set temperature is set again.</span>
</div>
</div>
<!-- /ko -->
@@ -214,7 +281,7 @@
<div class="control-group">
<label class="control-label"> Controlled IO</label>
<div class="controls">
<select data-bind="options: $root.rpi_outputs_regular, optionsText: 'label',
<select data-bind="options: $root.settings_outputs_regular, optionsText: 'label',
optionsValue: 'index_id', value: $data.controlled_io">
</select>
<span class="help-inline">When the event happen, you want control which IO?</span>
@@ -243,7 +310,7 @@
<div class="control-group">
<label class="control-label">{{ _('Default Duty Cycle') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: duty_cycle">
<input type="text" class="input-block-level" data-bind="value: default_duty_cycle">
<span class="help-inline">Value is in percentage, between 0 and 100</span>
</div>
</div>
@@ -291,6 +358,7 @@
</div>
</div>
<!-- /ko -->
<div class="control-group">
<a title="Delete IO" class="btn btn-danger pull-right" data-bind="click: function() { $parent.removeRpiOutput($data) }">
<i class="icon-trash"></i>
@@ -489,12 +557,13 @@
<div class="control-group">
<label class="control-label"> Controlled IO</label>
<div class="controls">
<select data-bind="options: $root.rpi_possible_outputs, optionsText: 'label',
<select data-bind="options: $root.settings_possible_outputs, optionsText: 'label',
optionsValue: 'index_id', value: $data.controlled_io">
</select>
<span class="help-inline">When the event happen, you want control which OUTPUT?</span>
</div>
</div>
<!-- ko if: ($root.isRegularOutput($data.controlled_io)) -->
<div class="control-group">
<label class="control-label">Set Controlled IO Value</label>
<div class="controls">
@@ -507,6 +576,7 @@
</div>
</div>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: ( $data.action_type() == "printer_control") -->
<div class="control-group">
<label class="control-label">{{ _('Printer Action') }}</label>
@@ -516,7 +586,7 @@
<option value="resume">Printer Resume</option>
<option value="pause">Printer Pause</option>
<option value="cancel">Printer Cancel</option>
<option value="stop_temperature_control">Stop Temperature Control</option>
<option value="stop_temp_hum_control">Stop Temperature Control</option>
</select>
<span class="help-inline"> You can use filament change on your filament detectors and add buttons to resume and pause the print job.</span>
</div>
@@ -541,7 +611,7 @@
</div>
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
<!-- ko if: ($data.input_type() == "temperature_sensor") -->
<div class="control-group">
<div class="controls">
@@ -575,6 +645,15 @@
</a>
<div id="advanced_enclosure" class="accordion-body collapse">
<form class="form-horizontal">
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: settingsViewModel.settings.plugins.enclosure.gcode_control"> {{ _('Enable gcode control') }}
</label>
<span class="help-inline">Use gcode to control outputs, check the documentation on
<a href=" https://github.com/vitormhenrique/OctoPrint-Enclosure">github</a> page</span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">

View File

@@ -13,7 +13,7 @@
<th class="humidity_actual" title="{{ _('Current humidity') }}">{{ _('Humidity') }}</th>
<!-- /ko -->
<!-- ko if: ($root.hasAnyTemperatureControl()) -->
<th class="temperature_control">{{ _('Control') }}</th>
<th class="temp_hum_control">{{ _('Control') }}</th>
<th class="temperature_target" title="{{ _('Current target temperature') }}">{{ _('Target') }}</th>
<!-- /ko -->
</tr>
@@ -45,28 +45,33 @@
<!-- ko if: ($root.linkedTemperatureControl(index_id())().length > 0 || $root.hasAnyTemperatureControl()) -->
<!-- ko with: $root.linkedTemperatureControl(index_id())()[0] -->
<th class="temperature_control" data-bind="html: label, attr: {title: label}"></th>
<th class="temp_hum_control" data-bind="html: label, attr: {title: label}"></th>
<td class="temperature_target">
<form class="form-inline" style="margin:0" data-bind="submit: function(element) { $root.setTemperature($data, element) }">
<div class="input-prepend input-append">
<input type="number" min="0" max="999" class="input-mini input-nospin" data-bind="value: temp_ctr_new_set_temp, valueUpdate: 'input', attr: {placeholder:$root.getCleanTemperature(temp_ctr_set_temp()), id: 'temp_control_' + index_id()}">
<input type="number" min="0" max="999" class="input-mini input-nospin" data-bind="enable: $root.isUser(), value: temp_ctr_new_set_value, valueUpdate: 'input', attr: {placeholder:$root.getCleanTemperature(temp_ctr_set_value()), id: 'temp_control_' + index_id()}">
<!-- ko if: ($data.temp_ctr_type == "heater" || $data.temp_ctr_type == "cooler") -->
<!-- ko if: ($parent.use_fahrenheit()) -->
<span class="add-on">&deg;F</span>
<span class="add-on">&deg;F</span>
<!-- /ko -->
<!-- ko ifnot: ($parent.use_fahrenheit()) -->
<span class="add-on">&deg;C</span>
<span class="add-on">&deg;C</span>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: ($data.temp_ctr_type == "dehumidifier") -->
<span class="add-on">%</span>
<!-- /ko -->
</div>
<div class="btn-group">
<button type="submit" data-bind="enable: $root.enableBtn()" class="btn btn-primary" title="{{ _('Set') }}">
<button type="submit" data-bind="enable: $root.isUser()" class="btn btn-primary" title="{{ _('Set') }}">
<i class="fa fa-check"></i>
</button>
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" data-bind="enable: $root.enableBtn()">
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" data-bind="enable: $root.isUser()">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0)" data-bind="click: $root.turnOffHeater">{{ _('Off') }}</a>
<a href="javascript:void(0)" data-bind="enable: $root.isUser(), click: $root.turnOffHeater">{{ _('Off') }}</a>
</li>
</ul>
</div>
@@ -77,7 +82,7 @@
<!-- ko if: ($root.hasAnyTemperatureControl()) -->
<!-- ko if: ( !$root.linkedTemperatureControl(index_id())().length > 0) -->
<td class="temperature_control"></td>
<td class="temp_hum_control"></td>
<td class="temperature_target"></td>
<!-- /ko -->
<!-- /ko -->
@@ -87,7 +92,7 @@
<!-- ko foreach: $root.linkedTemperatureControl(index_id())-->
<!-- ko ifnot: ($index() == 0) -->
<tr>
<th class="temperature_control" data-bind="html: label, attr: {title: label}"></th>
<th class="temp_hum_control" data-bind="html: label, attr: {title: label}"></th>
<td class="temperature_target">Set Temp</td>
</tr>
<!-- /ko -->
@@ -101,25 +106,144 @@
<!-- /ko -->
<!-- ko foreach: $root.rpi_outputs() -->
<!-- ko if: ($data.output_type() == "regular" || (!data.hide_btn_ui())) -->
<h4>
<span data-bind="html: label"> </span>
<!-- ko if: ($data.gpio_status()) -->
<span class="badge badge-success help-inline">on</span>
<!-- /ko -->
<!-- ko ifnot: ($data.gpio_status()) -->
<span class="badge badge-important help-inline">off</span>
<!-- /ko -->
</h4>
<!-- ko ifnot: ($data.hide_btn_ui()) -->
<!-- ko if: ($data.output_type() == "regular") -->
<h4>
<span data-bind="html: label"> </span>
<span class="badge">regular gpio</span>
<!-- ko if: ($data.gpio_status()) -->
<button data-bind="click: $root.handleIO" class="btn">Turn off</button>
<span class="badge badge-success help-inline">on</span>
<!-- /ko -->
<!-- ko ifnot: ($data.gpio_status()) -->
<button data-bind="click: $root.handleIO" class="btn">Turn on</button>
<span class="badge badge-important help-inline">off</span>
<!-- /ko -->
</h4>
<!-- /ko -->
<div>
<!-- ko if: ($data.gpio_status()) -->
<button data-bind="enable: $root.isUser(), click: $root.handleIO" class="btn">Turn off</button>
<!-- /ko -->
<!-- ko ifnot: ($data.gpio_status()) -->
<button data-bind="enable: $root.isUser(), click: $root.handleIO" class="btn">Turn on</button>
<!-- /ko -->
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "gcode_output") -->
<h4>
<span data-bind="html: label"> </span>
<span class="badge">gcode output</span>
</h4>
<div>
<button data-bind="enable: $root.isOperational(), click: $root.handleGcode" class="btn">Send gcode</button>
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "pwm") -->
<h4>
<span data-bind="html: label"> </span>
<span class="badge">pwm</span>
</h4>
<div class="input-append">
<input type="text" class="input-mini" data-bind="value: new_duty_cycle, valueUpdate: 'input', attr: {placeholder:$root.getDutyCycle(duty_cycle())}">
<button class="btn btn-input-inc" title="Set PWM" data-bind="enable: $root.isUser(), click: $root.handlePWM">
<i class="fa fa-check"></i>
</button>
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "neopixel_direct" || $data.output_type() == "neopixel_indirect") -->
<h4>
<span data-bind="html: label"> </span>
<span class="badge">neopixel</span>
</h4>
<div class="input-append neopixel-div">
<input type="text" class="input-block-level" data-bind="click: $root.showColorPicker(), value: new_neopixel_color, valueUpdate: 'input', attr: {placeholder:neopixel_color, name: 'colorpicker'}">
<button type="submit" class="btn btn-input-inc" title="Set Color" data-bind="enable: $root.isUser(), click: $root.handleNeopixel">
<i class="fa fa-check"></i>
</button>
</div>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "temp_hum_control") -->
<h4>
<span data-bind="html: label"> </span>
<span class="badge">temperature control</span>
<!-- ko if: ($data.temp_ctr_type() == "heater") -->
<span class="badge badge-warning">Heater</span>
<!-- /ko -->
<!-- ko if: ($data.temp_ctr_type() == "cooler") -->
<span class="badge badge-warning">Cooler</span>
<!-- /ko -->
<!-- ko if: ($data.temp_ctr_type() == "dehumidifier") -->
<span class="badge badge-warning">Dehumidifier</span>
<!-- /ko -->
</h4>
<!-- /ko -->
<!-- ko ifnot: (($data.output_type() == "regular" || $data.output_type() == "pwm") && $data.toggle_timer()) -->
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm") -->
<div>
<h5>
<!-- ko if: ($root.isUser()) -->
<span>Auto Startup</span>
<!-- ko if: ($data.auto_startup()) -->
<a href="#" data-bind="click: $root.switchAutoStartUp" class="fa fa-toggle-on enclosure-link" title="Disable Auto Startup"></a>
<!-- /ko -->
<!-- ko ifnot: ($data.auto_startup()) -->
<a href="#" data-bind="click: $root.switchAutoStartUp" class="fa fa-toggle-off enclosure-link" title="Enable Auto Startup"></a>
<!-- /ko -->
<!-- /ko -->
</h5>
<h5>
<!-- ko if: ($root.isUser()) -->
<span>Auto Shutdown</span>
<!-- ko if: ($data.auto_shutdown()) -->
<a href="#" data-bind="click: $root.switchAutoShutdown" class="fa fa-toggle-on enclosure-link" title="Disable Auto Shutdown"></a>
<!-- /ko -->
<!-- ko ifnot: ($data.auto_shutdown()) -->
<a href="#" data-bind="click: $root.switchAutoShutdown" class="fa fa-toggle-off enclosure-link" title="Enable Auto Shutdown"></a>
<!-- /ko -->
<!-- /ko -->
</h5>
<!-- ko if: ($data.output_type() == "temp_hum_control" && $data.temp_ctr_type() == "heater" && !$data.auto_shutdown()) -->
<span>
<span class="label label-important">Warning:</span><span> Consider making HEATER auto shutdown when print finish.</span>
</span>
<!-- /ko -->
</div>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: (($data.output_type() == "regular" || $data.output_type() == "pwm") && $data.toggle_timer()) -->
<h5>
<span>Time Toggle</span>
<span class="badge"> active</span>
</h5>
<!-- /ko -->
<br>
<!-- /ko -->
<!-- /ko -->
<!-- ko foreach: $root.rpi_inputs() -->
<!-- ko if: ($data.input_type() == "gpio" && $data.action_type() == "printer_control" && $data.printer_action() == "filament" ) -->
<h4>
<span data-bind="html: label"> </span>
<span class="badge">filament sensor</span>
<!-- ko if: ($root.isUser()) -->
<!-- ko if: ($data.filament_sensor_enabled()) -->
<a href="#" data-bind="click: $root.switchFilamentSensor" class="fa fa-toggle-on enclosure-link" title="Disable Filament Sensor"></a>
<!-- /ko -->
<!-- ko ifnot: ($data.filament_sensor_enabled()) -->
<a href="#" data-bind="click: $root.switchFilamentSensor" class="fa fa-toggle-off enclosure-link" title="Enable Filament Sensor"></a>
<!-- /ko -->
<!-- /ko -->
</h4>
<!-- /ko -->
<!-- /ko -->

View File

@@ -1,65 +0,0 @@
<div data-bind="foreach: settingsViewModel.settings.plugins.enclosure.rpi_outputs">
<!-- ko if: ($data.output_type() == "regular") -->
<h4>
<p data-bind="html: label"></p>
</h4>
<button data-bind="click: $root.handleIO" class="btn">Turn on</button>
<span class="glyphicon glyphicon-user glyphs-on" data-bind="click: $root.handleIO"></span>
<!-- /ko -->
</div>
<div data-bind="foreach: settingsViewModel.settings.plugins.enclosure.rpi_outputs">
<!-- ko if: ($data.output_type() == "regular") -->
<h4>
<p data-bind="html: label"></p>
</h4>
<button type="submit" data-bind="click: $root.handleIO.bind($data, [gpio_pin(), 'on']),
enable: $root.enableBtn(), attr: {id: 'btn_on_' + $data.gpio_pin()}" class="btn">Turn on</button>
<button type="submit" data-bind="click: $root.handleIO.bind($data, [gpio_pin(), 'off']),
enable: $root.enableBtn(), attr: {id: 'btn_off_' + $data.gpio_pin()}" class="btn">Turn off</button>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "pwm") -->
<h4>
<p data-bind="html: label"></p>
</h4>
<table class="table" style="width: 100%;align:left;margin-top:0px;margin-bottom:0px;">
<tr>
<th style="vertical-align: middle;border-top:0px;padding:0px">{{ _('Duty Cycle:') }}</th>
<td style="width: 20%;align:left;border-top:0px;padding:0px">
<input type="text" class="input-block-level" data-bind="attr: {id: 'duty_cycle_' + $data.gpio_pin()}">
</td>
<td style="width: 60%;align:left;border-top:0px;padding:0px">
<button type="submit" data-bind="click: $root.handlePWM.bind($data, [gpio_pin()]), enable: $root.enableBtn(),
attr: {id: 'btn_pwm_' + $data.gpio_pin()}" class="btn">Set PWM</button>
</td>
</tr>
</table>
<!-- /ko -->
<!-- ko if: ($data.output_type() == "neopixel") -->
<h4>
<p data-bind="html: label"></p>
</h4>
<table class="table" style="width: 100%;align:left;margin-top:0px;margin-bottom:0px;">
<tr>
<td style="width: 20%;align:left;border-top:0px;padding:0px">
<input type="text" class="input-small" data-bind="value: neopixel_color,
attr: {name: 'colorpicker', id: 'color_'+ $data.gpio_pin()} ,
click: $root.showColorPicker()">
</td>
<td style="width: 80%; align:left;border-top:0px;padding:0px">
<button type="submit" data-bind="click: $root.handleNeopixel.bind($data, [gpio_pin()]),
enable: $root.enableBtn(), attr: {id: 'btn_neopixel_' + $data.gpio_pin()}" class="btn">Set Color</button>
</td>
</tr>
</table>
<!-- /ko -->
</div>

View File

@@ -1,10 +0,0 @@
<!-- ko if: ($root.settingsViewModel.settings.plugins.enclosure.showTempNavbar()) -->
<div class="nav">
<p class="nav navbar-text">
<span data-bind="html: $root.navbarTemp"></span>
</p>
<p class="nav navbar-text">
<span data-bind="html: $root.navbarHum"></span>
</p>
</div>
<!-- /ko -->

View File

@@ -1,131 +0,0 @@
<form class="form-horizontal" id="enclosure_settings_temperature">
<h4>{{ _('Temperature Sensor') }}</h4>
<div data-bind="foreach: settingsViewModel.settings.plugins.enclosure.temperature_reading">
<div class="controls">
<label class="checkbox">
<input id="enableTemperatureReading" type="checkbox" data-bind="checked: isEnabled, click: $parent.fixUI()"> {{ _('Enable Temperature Reading') }}
</label>
</div>
<div id="temperature_reading_content">
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtModel">{{ _('Sensor Type') }}</label>
<div class="controls">
<select data-bind="value: sensorType">
<option value="">Select Sensor</option>
<option value="11">DHT11</option>
<option value="22">DHT22</option>
<option value="2302">AM2302</option>
<option value="18b20">DS18B20</option>
<option value="si7021">SI7021</option>
<option value="bme280">BME280</option>
<option value="tmp102">TMP102</option>
</select>
<span class="help-inline">
<span class="label label-important">Attention</span> You need to install and configure the necessary libraries for the temperature sensor, check
the documentation on
<a href=" https://github.com/vitormhenrique/OctoPrint-Enclosure">github</a> page</span>
</div>
</div>
<!-- ko if: ($data.sensorType() == "18b20") -->
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: gpioPin" value="4" disabled="true">
<span class="help-inline">GPIO pin for temperature sensor, recommended to use 4 as DS18B20 only works on pin 4</span>
</div>
</div>
<!-- /ko -->
<!-- ko if: ($data.sensorType() == "si7021") || ($data.sensorType() == "bme280") || ($data.sensorType() == "tmp102") -->
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
<div class="controls">
<input type="text" class="input-block-level" value="SCL / SDA" disabled="true">
<span class="help-inline">GPIO pin for temperature sensor need to connect the sensor to I2C. SCL Clock to GPIO 3 (SCL) and SDA Data to GPIO
2 (SDA)</span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Address') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: sensorAddress">
<span class="help-inline">Sensor address in HEX value, you can find it by runing
<code>i2cdetect -y 1</code> on your Raspberry Pi</span>
</div>
</div>
<!-- /ko -->
<!-- ko ifnot: ($data.sensorType() == "18b20") || ($data.sensorType() == "si7021") || ($data.sensorType() == "bme280") || ($data.sensorType() == "tmp102") -->
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: gpioPin">
<span class="help-inline">GPIO pin for temperature sensor, recommended to use 4 as DS18B20 only works on pin 4</span>
</div>
</div>
<!-- /ko -->
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: useFahrenheit"> {{ _('Use Fahrenheit Unit') }}
</label>
<span class="help-inline">Choose if you want to work with Celsius or Fahrenheit</span>
</div>
</div>
</div>
</form>
<form class="form-horizontal">
<h4>{{ _('Temperature Control') }}</h4>
<div data-bind="foreach: settingsViewModel.settings.plugins.enclosure.temperature_control">
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input id="enableHeater" type="checkbox" data-bind="checked: isEnabled, click: $parent.fixUI()"> {{ _('Enable Temperature Control') }}
</label>
</div>
</div>
<div id="temperature_control_content">
<div class="control-group">
<label class="control-label" for="settings-enclosure-heaterpin">{{ _('Temp Control Pin') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: gpioPin">
<span class="help-inline">GPIO pin used to control Heater.</span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: activeLow"> {{ _('Active Low') }}
</label>
<span class="help-inline">Active low means that the heater will turn on when receive a low signal (ground) from Raspbery PI</span>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Temp Control Type') }}</label>
<div class="controls">
<label class="radio">
<input type="radio" value="heater" name="optradio" data-bind="checked: controlType"> {{ _('Heater') }}</label>
</div>
<div class="controls">
<label class="radio">
<input type="radio" value="cooler" name="optradio" data-bind="checked: controlType"> {{ _('Cooler') }}</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: autoStartup"> {{ _('Auto Startup') }}
</label>
<span class="help-inline">Choose if you want to automatically startup temperature control when the print starts</span>
</div>
</div>
<!-- ko if: $data.autoStartup -->
<div class="control-group">
<label class="control-label">{{ _('Default Temperature') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: defaultTemp">
<span class="help-inline">Default temperature that temperature control will be set</span>
</div>
</div>
<!-- /ko -->
</div>
</div>
</form>

View File

@@ -1,64 +0,0 @@
{% if enableTemperatureGraph %}
<div class="row-fluid">
<div id="temperature-graph"></div>
</div>
{% endif %}
<div class="row-fluid">
<table id="temperature-table" class="table table-bordered table-hover">
<tr>
<th class="temperature_tool"></th>
<th class="temperature_actual" title="{{ _('Current actual temperature as reported by your printer') }}">{{ _('Actual') }}</th>
<th class="temperature_target" title="{{ _('Current target temperature as reported by your printer') }}">{{ _('Target') }}</th>
<th class="temperature_offset" title="{{ _('Offset to apply to temperature commands sent from files') }}">{{ _('Offset') }}</th>
</tr>
<!-- ko foreach: tools -->
<tr data-bind="template: { name: 'temprow-template' }"></tr>
<!-- /ko -->
<tr data-bind="template: { name: 'temprow-template', data: bedTemp }, visible: hasBed"></tr>
</table>
<script type="text/html" id="temprow-template">
<th class="temperature_tool" data-bind="text: name, attr: {title: name}"></th>
<td class="temperature_actual" data-bind="html: formatTemperature(actual()), attr: {title: formatTemperature(actual())}"></td>
<td class="temperature_target">
<form class="form-inline" style="margin:0" data-bind="submit: function(element) { $root.setTarget($data, element) }">
<div class="input-prepend input-append">
<button type="button" class="btn btn-input-dec" data-bind="click: $root.decrementTarget, enable: $root.isOperational() && $root.loginState.isUser()" title="{{ _('Fine adjust: -1°C') }}"><i class="fa fa-minus"></i></button>
<input type="number" min="0" max="999" class="input-mini input-nospin" style="width: 30px" data-bind="attr: {placeholder: cleanTemperature(target())}, value: newTarget, valueUpdate: 'input', enable: $root.isOperational() && $root.loginState.isUser(), event: { focus: function(d, e) {$root.handleFocus(e, 'target', $data) } }">
<span class="add-on">&deg;C</span>
<button type="button" class="btn btn-input-inc" data-bind="click: $root.incrementTarget, enable: $root.isOperational() && $root.loginState.isUser()" title="{{ _('Fine adjust: +1°C') }}"><i class="fa fa-plus"></i></button>
</div>
<div class="btn-group">
<button type="submit" data-bind="enable: $root.isOperational() && $root.loginState.isUser() && $data.newTargetValid()" class="btn btn-primary" title="{{ _('Set') }}"><i class="fa fa-check"></i></button>
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" data-bind="enable: $root.isOperational() && $root.loginState.isUser()">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0)" data-bind="click: $root.setTargetToZero">{{ _('Off') }}</a>
</li>
<li class="divider"></li>
<!-- ko foreach: $root.temperature_profiles -->
<li>
<a href="javascript:void(0)" data-bind="click: function() {$root.setTargetFromProfile($parent, $data);}, text: 'Set ' + name + ' (' + ($parent.key() == 'bed' ? bed : extruder) + '&deg;C)'"></a>
</li>
<!-- /ko -->
</ul>
</div>
</form>
</td>
<td class="temperature_offset">
<form class="form-inline" style="margin:0">
<div class="input-append">
<span class="input-mini uneditable-input text-right" style="width: 30px" data-bind="text: offset"></span>
<span class="add-on">&deg;C</span>
<button class="btn" title="{{ _('Change Offset') }}" data-bind="click: $root.changeOffset, enable: $root.isOperational() && $root.loginState.isUser()"><i class="fa fa-pencil"></i></button>
<button class="btn" title="{{ _('Delete Offset') }}" data-bind="click: $root.setOffsetToZero, enable: $root.isOperational() && $root.loginState.isUser()"><i class="fa fa-trash"></i></button>
</div>
</form>
</td>
</script>
</div>