output working

This commit is contained in:
Vitor de Miranda Henrique
2018-02-22 23:05:06 -06:00
parent 4496b32eae
commit c1047d020c
11 changed files with 989 additions and 654 deletions

View File

@@ -73,50 +73,45 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
# ~~ StartupPlugin mixin
def on_after_startup(self):
self.fix_data()
self.pwm_intances = []
self.event_queue = []
self.rpi_outputs = self._settings.get(["rpi_outputs"])
self.rpi_inputs = self._settings.get(["rpi_inputs"])
self.notifications = self._settings.get(["notifications"])
self.fix_data()
self.generate_temperature_control_status()
self.rpi_outputs_not_changed = []
self.start_timer()
self.setup_gpio()
self.configure_gpio()
self.update_output_ui()
self.update_ui()
# ~~ Blueprintplugin mixin
@octoprint.plugin.BlueprintPlugin.route("/setEnclosureTemperature", methods=["GET"])
def set_enclosure_temperature(self):
set_temperature = self.to_float(flask.request.values["set_temperature"])
set_temperature = self.to_float(
flask.request.values["set_temperature"])
index_id = self.to_int(flask.request.values["index_id"])
for temperature_control in [item for item in self.rpi_outputs if item['index_id'] == index_id]:
temperature_control['temperature_control_set_temperature'] = set_temperature
temperature_control['temp_ctr_set_temp'] = set_temperature
# self.handle_temperature_control()
self.handle_temperature_control()
return flask.jsonify(success=True)
@octoprint.plugin.BlueprintPlugin.route("/getEnclosureSetTemperature", methods=["GET"])
def get_enclosure_set_temperature(self):
result = []
for temperature_control_output in list(filter(lambda item:
item['output_type'] == 'temperature_control',
self.rpi_outputs)):
set_temperature = self.to_float(
temperature_control_output['temperature_control_set_temperature'])
result.append(set_temperature)
return flask.jsonify(result)
self.update_ui_set_temperature()
return flask.jsonify(success=True)
@octoprint.plugin.BlueprintPlugin.route("/clearGPIOMode", methods=["GET"])
def clear_gpio_mode(self):
GPIO.cleanup()
return flask.jsonify(success=True)
@octoprint.plugin.BlueprintPlugin.route("/updateBtnStatus", methods=["GET"])
def get_update_btn_status(self):
self.update_output_ui()
@octoprint.plugin.BlueprintPlugin.route("/updateUI", methods=["GET"])
def update_ui_requested(self):
self.update_ui()
return flask.jsonify(success=True)
@octoprint.plugin.BlueprintPlugin.route("/getOutputStatus", methods=["GET"])
@@ -135,12 +130,13 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
@octoprint.plugin.BlueprintPlugin.route("/getEnclosureTemperature", methods=["GET"])
def get_enclosure_temperature(self):
return flask.jsonify(self.temperature_sensor_data)
self.update_ui_current_temperature()
return flask.jsonify(success=True)
@octoprint.plugin.BlueprintPlugin.route("/setIO", methods=["GET"])
def set_io(self):
gpio_index = flask.request.values["index_id"]
value = True if flask.request.values["status"] == "on" else False
value = True if flask.request.values["status"] == 'true' else False
for rpi_output in self.rpi_outputs:
if self.to_int(gpio_index) == self.to_int(rpi_output['index_id']):
val = (not value) if rpi_output['active_low'] else value
@@ -255,11 +251,61 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
"Sensor %s Temperature: %s humidity %s", sensor['label'], temp, hum)
sensor_data.append(
dict(index_id=sensor['index_id'], temperature=temp, humidity=hum))
self._plugin_manager.send_plugin_message(
self._identifier, dict(sensor_data=sensor_data))
self.temperature_sensor_data = sensor_data
self.update_ui()
self.handle_temperature_control()
# self.handle_temperature_events()
self.handle_temperature_events()
except Exception as ex:
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
message = template.format(
type(ex).__name__, inspect.currentframe().f_code.co_name, ex.args)
self._logger.warn(message)
pass
def update_ui(self):
self.update_ui_outputs()
self.update_ui_current_temperature()
self.update_ui_set_temperature()
def update_ui_current_temperature(self):
self._plugin_manager.send_plugin_message(
self._identifier, dict(sensor_data=self.temperature_sensor_data))
def update_ui_set_temperature(self):
result = []
for temp_crt_output in list(filter(lambda item:
item['output_type'] == 'temperature_control',
self.rpi_outputs)):
set_temperature = self.to_float(
temp_crt_output['temp_ctr_set_temp'])
result.append(
dict(index_id=temp_crt_output['index_id'], set_temperature=set_temperature))
result.append(set_temperature)
self._plugin_manager.send_plugin_message(
self._identifier, dict(set_temperature=result))
def update_ui_outputs(self):
try:
gpio_status = []
pwm_status = []
for rpi_output in self.rpi_outputs:
index = self.to_int(rpi_output['index_id'])
pin = self.to_int(rpi_output['gpio_pin'])
if rpi_output['output_type'] == 'regular':
val = GPIO.input(pin) if not rpi_output['active_low'] else (
not GPIO.input(pin))
gpio_status.append(dict(index_id=index, status=val))
if rpi_output['output_type'] == 'pwm':
for pwm in self.pwm_intances:
if pin in pwm:
if 'duty_cycle' in pwm:
pwmVal = pwm['duty_cycle']
val = self.to_int(pwmVal)
else:
val = 100
pwm_status.append(dict(index_id=index, pwm_value=val))
self._plugin_manager.send_plugin_message(
self._identifier, dict(rpi_output=gpio_status, rpi_output_pwm=pwm_status))
except Exception as ex:
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
message = template.format(
@@ -269,25 +315,25 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
def get_sensor_data(self, sensor):
try:
if sensor['temperature_sensor_type'] in ["11", "22", "2302"]:
self._logger.info("temperature_sensor_type dht")
if sensor['temp_sensor_type'] in ["11", "22", "2302"]:
self._logger.info("temp_sensor_type dht")
temp, hum = self.read_dht_temp(
sensor['temperature_sensor_type'], sensor['gpio_pin'])
elif sensor['temperature_sensor_type'] == "18b20":
sensor['temp_sensor_type'], sensor['gpio_pin'])
elif sensor['temp_sensor_type'] == "18b20":
temp = self.read_18b20_temp(sensor['ds18b20_serial'])
hum = 0
elif sensor['temperature_sensor_type'] == "bme280":
elif sensor['temp_sensor_type'] == "bme280":
temp, hum = self.read_bme280_temp(
sensor['temperature_sensor_address'])
elif sensor['temperature_sensor_type'] == "si7021":
sensor['temp_sensor_address'])
elif sensor['temp_sensor_type'] == "si7021":
temp, hum = self.read_si7021_temp(
sensor['temperature_sensor_address'])
elif sensor['temperature_sensor_type'] == "tmp102":
sensor['temp_sensor_address'])
elif sensor['temp_sensor_type'] == "tmp102":
temp = self.read_tmp102_temp(
sensor['temperature_sensor_address'])
sensor['temp_sensor_address'])
hum = 0
else:
self._logger.info("temperature_sensor_type no match")
self._logger.info("temp_sensor_type no match")
temp = 0
hum = 0
if temp != -1 and hum != -1:
@@ -304,12 +350,14 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
def handle_temperature_events(self):
for temperature_alarm in [item for item in self.rpi_outputs if item['output_type'] == 'temperature_alarm']:
if self.to_float(temperature_alarm['alarm_set_temperature']) == 0:
set_temperature = self.to_float(
temperature_alarm['alarm_set_temp'])
if int(set_temperature) is 0:
continue
linked_data = [item for item in self.temperature_sensor_data if item['index_id'] ==
temperature_alarm['linked_temperature_sensor']].pop()
sensor_temperature = linked_data['temperature']
if self.to_float(temperature_alarm['alarm_set_temperature']) < sensor_temperature:
temperature_alarm['linked_temp_sensor']].pop()
sensor_temperature = self.to_float(linked_data['temperature'])
if set_temperature < sensor_temperature:
for rpi_controlled_output in self.rpi_outputs:
if self.to_int(temperature_alarm['controlled_io']) == self.to_int(rpi_controlled_output['index_id']):
val = GPIO.LOW if rpi_controlled_output['active_low'] else GPIO.HIGH
@@ -425,9 +473,17 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
for temperature_control in list(filter(lambda item: item['output_type'] == 'temperature_control', self.rpi_outputs)):
set_temperature = self.to_float(
temperature_control['temperature_control_set_temperature'])
temperature_control['temp_ctr_set_temp'])
temp_deadband = self.to_float(
temperature_control['temp_ctr_deadband'])
max_temp = self.to_float(
temperature_control['temp_ctr_max_temp'])
linked_id = temperature_control['linked_temperature_sensor']
linked_id = temperature_control['linked_temp_sensor']
previous_status = filter(
lambda item: item['index_id'] == temperature_control['index_id'],
self.temperature_control_status).pop()['status']
if set_temperature == 0:
current_status = False
@@ -435,17 +491,22 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
linked_data = [
data for data in self.temperature_sensor_data if data['index_id'] == linked_id].pop()
current_temperature = self.to_float(linked_data['temperature'])
current_temperature = self.to_float(
linked_data['temperature'])
current_status = self.to_float(set_temperature) > self.to_float(current_temperature)
if set_temperature - temp_deadband > current_temperature:
current_status = True
elif set_temperature + temp_deadband < current_temperature:
current_status = False
else:
current_status = previous_status
if temperature_control['temperature_control_type'] is 'cooler':
if temperature_control['temp_ctr_type'] is 'cooler':
current_status = not current_status
previous_status = filter(
lambda item: item['index_id'] == temperature_control['index_id'],
self.temperature_control_status).pop()['status']
if temperature_control['temp_ctr_type'] is 'heater' and int(max_temp) is not 0 and max_temp < current_temperature:
temperature_control['temp_ctr_set_temp'] = 0
current_status = False
if current_status != previous_status:
if current_status:
self._logger.info(
@@ -463,10 +524,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
if control_status['index_id'] == temperature_control['index_id']:
control_status['status'] = current_status
except Exception as ex:
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
message = template.format(
type(ex).__name__, inspect.currentframe().f_code.co_name, ex.args)
self._logger.warn(message)
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
message = template.format(
type(ex).__name__, inspect.currentframe().f_code.co_name, ex.args)
self._logger.warn(message)
def setup_gpio(self):
try:
@@ -474,12 +535,13 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
setMode = GPIO.BOARD if self._settings.get(
["useBoardPinNumber"]) else GPIO.BCM
if currentMode is None:
gpios = list(filter(lambda item: item['output_type'] == 'regular' or
item['output_type'] == 'pwm' or
item['output_type'] == 'temperature_control' or
item['output_type'] == 'neopixel_direct', self.rpi_outputs))
gpios.append(list(filter(
lambda item: item['input_type'] == 'gpio', self.rpi_inputs)))
outputs = list(filter(lambda item: item['output_type'] == 'regular' or
item['output_type'] == 'pwm' or
item['output_type'] == 'temperature_control' or
item['output_type'] == 'neopixel_direct', self.rpi_outputs))
inputs = list(filter(
lambda item: item['input_type'] == 'gpio', self.rpi_inputs))
gpios = outputs + inputs
if gpios:
GPIO.setmode(setMode)
tempstr = "BOARD" if setMode == GPIO.BOARD else "BCM"
@@ -726,7 +788,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
GPIO.output(gpio, value)
if self._settings.get(["debug"]) is True:
self._logger.info("Writing on gpio: %s value %s", gpio, value)
self.update_output_ui()
self.update_ui()
except Exception as ex:
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
message = template.format(
@@ -745,7 +807,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
if self._settings.get(["debug"]) is True:
self._logger.info(
"Writing PWM on gpio: %s value %s", gpio, pwmValue)
self.update_output_ui()
self.update_ui()
break
except Exception as ex:
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
@@ -754,51 +816,6 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
self._logger.warn(message)
pass
def update_output_ui(self):
try:
gpio_status = []
pwm_status = []
for rpi_output in self.rpi_outputs:
pin = self.to_int(rpi_output['gpio_pin'])
if rpi_output['output_type'] == 'regular':
val = GPIO.input(pin) if not rpi_output['active_low'] else (
not GPIO.input(pin))
gpio_status.append({pin: val})
if rpi_output['output_type'] == 'pwm':
for pwm in self.pwm_intances:
if pin in pwm:
if 'duty_cycle' in pwm:
pwmVal = pwm['duty_cycle']
val = self.to_int(pwmVal)
else:
val = 100
pwm_status.append({pin: val})
# self._logger.info("result_pwm: %s", result_pwm)
self._plugin_manager.send_plugin_message(
self._identifier, dict(rpi_output=gpio_status, rpi_output_pwm=pwm_status))
except Exception as ex:
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
message = template.format(
type(ex).__name__, inspect.currentframe().f_code.co_name, ex.args)
self._logger.warn(message)
pass
def update_set_temperature(self):
try:
result = []
for filament_sensor in list(filter(lambda item: item['output_type'] == 'temperature_control', self.rpi_outputs)):
result.append(dict(
index_id=filament_sensor['index_id'], temperature=filament_sensor['temperature_control_set_temperature']))
self._plugin_manager.send_plugin_message(
self._identifier, dict(set_temperature=result))
except Exception as ex:
template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
message = template.format(
type(ex).__name__, inspect.currentframe().f_code.co_name, ex.args)
self._logger.warn(message)
pass
def get_output_list(self):
result = []
for rpi_output in self.rpi_outputs:
@@ -851,7 +868,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
def on_event(self, event, payload):
if event == Events.CONNECTED:
self.update_output_ui()
self.update_ui()
if event == Events.PRINT_RESUMED:
self.start_filament_detection()
@@ -889,7 +906,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
args=[gpio_pin, ledCount, ledBrightness, red, green, blue, address]))
if rpi_output['auto_startup'] and rpi_output['output_type'] == 'temperature_control':
rpi_output['temperature_control_set_temperature'] = rpi_output['temperature_control_default_temperature']
rpi_output['temp_ctr_set_temp'] = rpi_output['temp_ctr_default_temp']
self.update_set_temperature()
for task in self.event_queue:
task.start()
@@ -933,9 +950,6 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
# ~~ SettingsPlugin mixin
def on_settings_save(self, data):
# self._logger.info("data: %s", data)
outputsBeforeSave = self.get_output_list()
octoprint.plugin.SettingsPlugin.on_settings_save(self, data)
self.rpi_outputs = self._settings.get(["rpi_outputs"])
@@ -996,9 +1010,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
# ~~ AssetPlugin mixin
def get_assets(self):
return dict(
js=["js/enclosure.js", "js/bootstrap-colorpicker.min.js"],
css=["css/bootstrap-colorpicker.css", "css/enclosure.css"],
less=['less/my_styles.less']
js=["js/enclosure.js", "js/bootstrap-colorpicker.min.js", "js/bootstrap2-toggle.js"],
css=["css/bootstrap-colorpicker.css", "css/enclosure.css", "css/bootstrap2-toggle.css"]
)
# ~~ Softwareupdate hook

View File

@@ -1,230 +1,230 @@
/*!
* Bootstrap Colorpicker v2.5.1
* https://itsjavi.com/bootstrap-colorpicker/
*
* Originally written by (c) 2012 Stefan Petre
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
*/
.colorpicker-saturation {
width: 100px;
height: 100px;
background-image: url("../img/bootstrap-colorpicker/saturation.png");
cursor: crosshair;
float: left;
}
.colorpicker-saturation i {
display: block;
height: 5px;
width: 5px;
border: 1px solid #000;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
position: absolute;
top: 0;
left: 0;
margin: -4px 0 0 -4px;
}
.colorpicker-saturation i b {
display: block;
height: 5px;
width: 5px;
border: 1px solid #fff;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.colorpicker-hue,
.colorpicker-alpha {
width: 15px;
height: 100px;
float: left;
cursor: row-resize;
margin-left: 4px;
margin-bottom: 4px;
}
.colorpicker-hue i,
.colorpicker-alpha i {
display: block;
height: 1px;
background: #000;
border-top: 1px solid #fff;
position: absolute;
top: 0;
left: 0;
width: 100%;
margin-top: -1px;
}
.colorpicker-hue {
background-image: url("../img/bootstrap-colorpicker/hue.png");
}
.colorpicker-alpha {
background-image: url("../img/bootstrap-colorpicker/alpha.png");
display: none;
}
.colorpicker-saturation,
.colorpicker-hue,
.colorpicker-alpha {
background-size: contain;
}
.colorpicker {
padding: 4px;
min-width: 130px;
margin-top: 1px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
z-index: 2500;
}
.colorpicker:before,
.colorpicker:after {
display: table;
content: "";
line-height: 0;
}
.colorpicker:after {
clear: both;
}
.colorpicker:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: -7px;
left: 6px;
}
.colorpicker:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
top: -6px;
left: 7px;
}
.colorpicker div {
position: relative;
}
.colorpicker.colorpicker-with-alpha {
min-width: 140px;
}
.colorpicker.colorpicker-with-alpha .colorpicker-alpha {
display: block;
}
.colorpicker-color {
height: 10px;
margin-top: 5px;
clear: both;
background-image: url("../img/bootstrap-colorpicker/alpha.png");
background-position: 0 100%;
}
.colorpicker-color div {
height: 10px;
}
.colorpicker-selectors {
display: none;
height: 10px;
margin-top: 5px;
clear: both;
}
.colorpicker-selectors i {
cursor: pointer;
float: left;
height: 10px;
width: 10px;
}
.colorpicker-selectors i + i {
margin-left: 3px;
}
.colorpicker-element .input-group-addon i,
.colorpicker-element .add-on i {
display: inline-block;
cursor: pointer;
height: 16px;
vertical-align: text-top;
width: 16px;
}
.colorpicker.colorpicker-inline {
position: relative;
display: inline-block;
float: none;
z-index: auto;
}
.colorpicker.colorpicker-horizontal {
width: 110px;
min-width: 110px;
height: auto;
}
.colorpicker.colorpicker-horizontal .colorpicker-saturation {
margin-bottom: 4px;
}
.colorpicker.colorpicker-horizontal .colorpicker-color {
width: 100px;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue,
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
width: 100px;
height: 15px;
float: left;
cursor: col-resize;
margin-left: 0px;
margin-bottom: 4px;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue i,
.colorpicker.colorpicker-horizontal .colorpicker-alpha i {
display: block;
height: 15px;
background: #ffffff;
position: absolute;
top: 0;
left: 0;
width: 1px;
border: none;
margin-top: 0px;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue {
background-image: url("../img/bootstrap-colorpicker/hue-horizontal.png");
}
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
background-image: url("../img/bootstrap-colorpicker/alpha-horizontal.png");
}
.colorpicker-right:before {
left: auto;
right: 6px;
}
.colorpicker-right:after {
left: auto;
right: 7px;
}
.colorpicker-no-arrow:before {
border-right: 0;
border-left: 0;
}
.colorpicker-no-arrow:after {
border-right: 0;
border-left: 0;
}
.colorpicker.colorpicker-visible,
.colorpicker-alpha.colorpicker-visible,
.colorpicker-saturation.colorpicker-visible,
.colorpicker-hue.colorpicker-visible,
.colorpicker-selectors.colorpicker-visible {
display: block;
}
.colorpicker.colorpicker-hidden,
.colorpicker-alpha.colorpicker-hidden,
.colorpicker-saturation.colorpicker-hidden,
.colorpicker-hue.colorpicker-hidden,
.colorpicker-selectors.colorpicker-hidden {
display: none;
}
.colorpicker-inline.colorpicker-visible {
display: inline-block;
}
/*!
* Bootstrap Colorpicker v2.5.1
* https://itsjavi.com/bootstrap-colorpicker/
*
* Originally written by (c) 2012 Stefan Petre
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
*/
.colorpicker-saturation {
width: 100px;
height: 100px;
background-image: url("../img/bootstrap-colorpicker/saturation.png");
cursor: crosshair;
float: left;
}
.colorpicker-saturation i {
display: block;
height: 5px;
width: 5px;
border: 1px solid #000;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
position: absolute;
top: 0;
left: 0;
margin: -4px 0 0 -4px;
}
.colorpicker-saturation i b {
display: block;
height: 5px;
width: 5px;
border: 1px solid #fff;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.colorpicker-hue,
.colorpicker-alpha {
width: 15px;
height: 100px;
float: left;
cursor: row-resize;
margin-left: 4px;
margin-bottom: 4px;
}
.colorpicker-hue i,
.colorpicker-alpha i {
display: block;
height: 1px;
background: #000;
border-top: 1px solid #fff;
position: absolute;
top: 0;
left: 0;
width: 100%;
margin-top: -1px;
}
.colorpicker-hue {
background-image: url("../img/bootstrap-colorpicker/hue.png");
}
.colorpicker-alpha {
background-image: url("../img/bootstrap-colorpicker/alpha.png");
display: none;
}
.colorpicker-saturation,
.colorpicker-hue,
.colorpicker-alpha {
background-size: contain;
}
.colorpicker {
padding: 4px;
min-width: 130px;
margin-top: 1px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
z-index: 2500;
}
.colorpicker:before,
.colorpicker:after {
display: table;
content: "";
line-height: 0;
}
.colorpicker:after {
clear: both;
}
.colorpicker:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: -7px;
left: 6px;
}
.colorpicker:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
top: -6px;
left: 7px;
}
.colorpicker div {
position: relative;
}
.colorpicker.colorpicker-with-alpha {
min-width: 140px;
}
.colorpicker.colorpicker-with-alpha .colorpicker-alpha {
display: block;
}
.colorpicker-color {
height: 10px;
margin-top: 5px;
clear: both;
background-image: url("../img/bootstrap-colorpicker/alpha.png");
background-position: 0 100%;
}
.colorpicker-color div {
height: 10px;
}
.colorpicker-selectors {
display: none;
height: 10px;
margin-top: 5px;
clear: both;
}
.colorpicker-selectors i {
cursor: pointer;
float: left;
height: 10px;
width: 10px;
}
.colorpicker-selectors i + i {
margin-left: 3px;
}
.colorpicker-element .input-group-addon i,
.colorpicker-element .add-on i {
display: inline-block;
cursor: pointer;
height: 16px;
vertical-align: text-top;
width: 16px;
}
.colorpicker.colorpicker-inline {
position: relative;
display: inline-block;
float: none;
z-index: auto;
}
.colorpicker.colorpicker-horizontal {
width: 110px;
min-width: 110px;
height: auto;
}
.colorpicker.colorpicker-horizontal .colorpicker-saturation {
margin-bottom: 4px;
}
.colorpicker.colorpicker-horizontal .colorpicker-color {
width: 100px;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue,
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
width: 100px;
height: 15px;
float: left;
cursor: col-resize;
margin-left: 0px;
margin-bottom: 4px;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue i,
.colorpicker.colorpicker-horizontal .colorpicker-alpha i {
display: block;
height: 15px;
background: #ffffff;
position: absolute;
top: 0;
left: 0;
width: 1px;
border: none;
margin-top: 0px;
}
.colorpicker.colorpicker-horizontal .colorpicker-hue {
background-image: url("../img/bootstrap-colorpicker/hue-horizontal.png");
}
.colorpicker.colorpicker-horizontal .colorpicker-alpha {
background-image: url("../img/bootstrap-colorpicker/alpha-horizontal.png");
}
.colorpicker-right:before {
left: auto;
right: 6px;
}
.colorpicker-right:after {
left: auto;
right: 7px;
}
.colorpicker-no-arrow:before {
border-right: 0;
border-left: 0;
}
.colorpicker-no-arrow:after {
border-right: 0;
border-left: 0;
}
.colorpicker.colorpicker-visible,
.colorpicker-alpha.colorpicker-visible,
.colorpicker-saturation.colorpicker-visible,
.colorpicker-hue.colorpicker-visible,
.colorpicker-selectors.colorpicker-visible {
display: block;
}
.colorpicker.colorpicker-hidden,
.colorpicker-alpha.colorpicker-hidden,
.colorpicker-saturation.colorpicker-hidden,
.colorpicker-hue.colorpicker-hidden,
.colorpicker-selectors.colorpicker-hidden {
display: none;
}
.colorpicker-inline.colorpicker-visible {
display: inline-block;
}
/*# sourceMappingURL=bootstrap-colorpicker.css.map */

View File

@@ -0,0 +1,85 @@
/*! ========================================================================
* 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

@@ -1,42 +1,54 @@
#enclosure-table {
table-layout: fixed;
width: 100%;
margin-top: 20px;
}
#enclosure-table th,
#enclosure-table td {
vertical-align: middle;
text-align: center;
}
#enclosure-table th.temperature_sensor,
#enclosure-table td.temperature_sensor {
width: 15%;
text-align: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#enclosure-table th.temperature_actual,
#enclosure-table td.temperature_actual {
width: 20%;
}
#enclosure-table th.humidity_actual,
#enclosure-table td.humidity_actual {
width: 20%;
}
#enclosure-table th.temperature_control,
#enclosure-table td.temperature_control {
width: 15%;
}
#enclosure-table th.temperature_target,
#enclosure-table td.temperature_target {
width: 30%;
overflow: visible;
}
#enclosure-table {
table-layout: fixed;
width: 100%;
margin-top: 20px;
}
#enclosure-table th,
#enclosure-table td {
vertical-align: middle;
text-align: center;
}
#enclosure-table th.temperature_sensor,
#enclosure-table td.temperature_sensor {
width: 15%;
text-align: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#enclosure-table th.temperature_actual,
#enclosure-table td.temperature_actual {
width: 20%;
}
#enclosure-table th.humidity_actual,
#enclosure-table td.humidity_actual {
width: 20%;
}
#enclosure-table th.temperature_control,
#enclosure-table td.temperature_control {
width: 15%;
}
#enclosure-table th.temperature_target,
#enclosure-table td.temperature_target {
width: 30%;
overflow: visible;
}
.glyphs-on {
color: blue;
text-shadow: 4px 4px 15px blue;
}
.glyphs-off {
color: red;
text-shadow: 4px 4px 15px red;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,180 @@
/*! ========================================================================
* 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

@@ -38,7 +38,7 @@ $(function () {
self.notifications = ko.observable();
self.humidityCapableSensor = function(sensor){
if (['11', '22'].indexOf(sensor) >= 0){
if (['11', '22', '2302', 'bme280', 'si7021'].indexOf(sensor) >= 0){
return true;
}
return false;
@@ -47,55 +47,80 @@ $(function () {
self.linkedTemperatureControl = function(sensor_index){
return ko.pureComputed(function () {
return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs(), function (item) {
return (item.linked_temperature_sensor() == sensor_index);
if (item.linked_temp_sensor){
return (item.linked_temp_sensor() == sensor_index);
}else{
return false;
}
});
});
};
self.hasAnySensorWithHumidity = function(){
return_value = false;
self.rpi_inputs_temperature_sensors().forEach(function (sensor) {
if (self.humidityCapableSensor(sensor.temperature_sensor_type())) {
return true;
if (self.humidityCapableSensor(sensor.temp_sensor_type())) {
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") {
return_value = true
return false;
}
});
return false;
return return_value;
};
self.onDataUpdaterPluginMessage = function (plugin, data) {
if (typeof plugin == 'undefined'){
return;
}
if (plugin != "enclosure") {
return;
}
if (data.hasOwnProperty("sensor_data")) {
data.sensor_data.forEach(function (sensor_data) {
var linked_temperature_sensor = ko.utils.arrayFilter(self.rpi_inputs(), function (temperature_sensor) {
return (sensor_data['id'] == temperature_sensor.index_id());
var linked_temp_sensor = ko.utils.arrayFilter(self.rpi_inputs_temperature_sensors(), function (temperature_sensor) {
return (sensor_data['index_id'] == temperature_sensor.index_id());
}).pop();
if (linked_temperature_sensor){
linked_temperature_sensor.temperature_sensor_temperature(sensor_data['temperature'])
linked_temperature_sensor.temperature_sensor_humidity(sensor_data['humidity'])
if (linked_temp_sensor){
linked_temp_sensor.temp_sensor_temp(sensor_data['temperature'])
linked_temp_sensor.temp_sensor_humidity(sensor_data['humidity'])
}
})
// linked_item.temperature_sensor_temperature()
};
}
if (data.hasOwnProperty("set_temperature")) {
data.set_temperature.forEach(function (set_temperature) {
var linked_temp_control = ko.utils.arrayFilter(self.rpi_outputs(), function (temp_control) {
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'])
}
})
}
// if (data.hasOwnProperty("enclosureHumidity")) {
// self.enclosureHumidity(data.enclosureHumidity);
// self.navbarHum(_.sprintf("Hum: %.1f%%", data.enclosureHumidity));
// }
// if (data.hasOwnProperty("enclosureSetTemp")) {
// if (parseFloat(data.enclosureSetTemp) > 0.0) {
// $("#enclosureSetTemp").attr("placeholder", data.enclosureSetTemp);
// } else {
// $("#enclosureSetTemp").attr("placeholder", "off");
// }
// }
if (data.hasOwnProperty("rpi_output")) {
data.rpi_output.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'])
}
})
}
// if (!data.rpi_output) {
// data.rpi_output = self.previous_gpio_status;
@@ -153,12 +178,9 @@ $(function () {
return temp;
}
self.onBeforeBinding = function () {
self.bindSettings = function(){
self.rpi_outputs(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs());
self.rpi_inputs(self.settingsViewModel.settings.plugins.enclosure.rpi_inputs());
self.debug(self.settingsViewModel.settings.plugins.enclosure.debug())
self.debug_temperature_log(self.settingsViewModel.settings.plugins.enclosure.debug_temperature_log())
self.filament_sensor_gcode(self.settingsViewModel.settings.plugins.enclosure.filament_sensor_gcode())
@@ -166,6 +188,10 @@ $(function () {
self.notification_event_name(self.settingsViewModel.settings.plugins.enclosure.notification_event_name())
self.notification_api_key(self.settingsViewModel.settings.plugins.enclosure.notification_api_key())
self.notifications(self.settingsViewModel.settings.plugins.enclosure.notifications())
};
self.onBeforeBinding = function () {
self.bindSettings();
// self.settings = self.settingsViewModel.settings.plugins.enclosure;
// self.temperature_reading(self.settings.temperature_reading());
@@ -173,8 +199,11 @@ $(function () {
};
self.onStartupComplete = function () {
// var test = self.linkedTemperatureControl(1);
// console.log(test());
// self.requestEnclosureSetTemperature();
// $(".toggle").bootstrapToggle();
// self.requestEnclosureTemperature();
};
self.onDataUpdaterReconnect = function () {
@@ -192,7 +221,8 @@ $(function () {
}
self.onSettingsHidden = function () {
// self.getUpdateBtnStatus();
// self.bindSettings();
// self.requestEnclosureTemperature();
};
self.getRegularOutputs = function () {
@@ -202,7 +232,7 @@ $(function () {
};
self.setTemperature = function (item, form) {
var newSetTemperature = item.temperature_control_new_temperature();
var newSetTemperature = item.temp_ctr_new_set_temp();
if (form !== undefined) {
$(form).find("input").blur();
}
@@ -215,8 +245,8 @@ $(function () {
dataType: "json",
data: request,
success: function (data) {
item.temperature_control_new_temperature("");
item.temperature_control_set_temperature(newSetTemperature);
item.temp_ctr_new_set_temp("");
item.temp_ctr_set_temp(newSetTemperature);
},
error: function (textStatus, errorThrown) {
new PNotify({
@@ -246,7 +276,7 @@ $(function () {
label: ko.observable("Ouput " + nextIndex),
output_type: ko.observable("regular"),
gpio_pin: ko.observable(0),
gpio_status: ko.observable(0),
gpio_status: ko.observable(false),
active_low: ko.observable(true),
auto_startup: ko.observable(false),
controlled_io: ko.observable(0),
@@ -254,14 +284,14 @@ $(function () {
startup_time: ko.observable(0),
auto_shutdown: ko.observable(false),
shutdown_time: ko.observable(0),
linked_temperature_sensor: ko.observable(),
alarm_set_temperature: ko.observable(0),
temperature_control_type: ko.observable(""),
temperature_control_deadband: ko.observable(0),
temperature_control_set_temperature: ko.observable(0),
temperature_control_new_temperature: ko.observable(""),
temperature_control_default_temperature: ko.observable(0),
temperature_control_max_temperature: ko.observable(0),
linked_temp_sensor: ko.observable(),
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_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),
@@ -293,10 +323,10 @@ $(function () {
input_type: ko.observable("gpio"),
gpio_pin: ko.observable(0),
input_pull_resistor: ko.observable("input_pull_up"),
temperature_sensor_type: ko.observable("DS18B20"),
temperature_sensor_address: ko.observable(""),
temperature_sensor_temperature: ko.observable(0),
temperature_sensor_humidity: ko.observable(0),
temp_sensor_type: ko.observable("DS18B20"),
temp_sensor_address: ko.observable(""),
temp_sensor_temp: ko.observable(""),
temp_sensor_humidity: ko.observable(""),
ds18b20_serial: ko.observable(""),
use_fahrenheit: ko.observable(false),
action_type: ko.observable("gpio_control"),
@@ -304,7 +334,7 @@ $(function () {
controlled_io_set_value: ko.observable("low"),
edge: ko.observable("fall"),
printer_action: ko.observable("filament"),
temperature_sensor_navbar: ko.observable(true),
temp_sensor_navbar: ko.observable(true),
filament_sensor_timeout: ko.observable(120),
filament_sensor_enabled: ko.observable(true)
});
@@ -315,7 +345,7 @@ $(function () {
};
self.turnOffHeater = function (item) {
console.log(item);
// console.log(item);
// $.ajax({
// url: self.buildPluginUrl("/setEnclosureTemperature"),
// type: "GET",
@@ -345,15 +375,15 @@ $(function () {
});
};
self.getUpdateBtnStatus = function () {
self.getUpdateUI = function () {
$.ajax({
url: self.buildPluginUrl("/getUpdateBtnStatus"),
url: self.buildPluginUrl("/updateUI"),
type: "GET"
});
};
self.requestEnclosureTemperature = function () {
console.log("Requesting enclosure temperature");
return $.ajax({
type: "GET",
url: self.buildPluginUrl("/getEnclosureTemperature"),
@@ -362,23 +392,33 @@ $(function () {
};
self.requestEnclosureSetTemperature = function () {
return $.ajax({
type: "GET",
$.ajax({
url: self.buildPluginUrl("/getEnclosureSetTemperature"),
async: false
}).responseText;
type: "GET",
error: function (textStatus, errorThrown) {
new PNotify({
title: "Enclosure",
text: "Error geting set temperatures",
type: "error"
});
}});
};
self.handleIO = function (data, event) {
self.handleIO = function (item, form) {
var request = {
"status": !item.gpio_status(),
"index_id": item.index_id()
};
$.ajax({
type: "GET",
dataType: "json",
data: {
"io": data[0],
"status": data[1]
},
data: request,
url: self.buildPluginUrl("/setIO"),
async: false
success: function (data) {
self.getUpdateUI();
}
});
};

View File

@@ -146,7 +146,7 @@
<label class="control-label">Temperature Sensor</label>
<div class="controls">
<select data-bind="options: $root.rpi_inputs_temperature_sensors, optionsText: 'label',
optionsValue: 'index_id', value: $data.linked_temperature_sensor">
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>
@@ -157,33 +157,33 @@
<label class="control-label">{{ _('Temp Control Type') }}</label>
<div class="controls">
<label class="radio">
<input type="radio" value="heater" name="optradio" data-bind="checked: temperature_control_type"> {{ _('Heater') }}</label>
<input type="radio" value="heater" name="optradio" data-bind="checked: temp_ctr_type"> {{ _('Heater') }}</label>
</div>
<div class="controls">
<label class="radio">
<input type="radio" value="cooler" name="optradio" data-bind="checked: temperature_control_type"> {{ _('Cooler') }}</label>
<input type="radio" value="cooler" name="optradio" data-bind="checked: temp_ctr_type"> {{ _('Cooler') }}</label>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Default Temperature') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: temperature_control_default_temperature">
<span class="help-inline">Default temperature that temperature control will be set</span>
<input type="text" class="input-block-level" data-bind="value: temp_ctr_default_temp">
<span class="help-inline">Default temperature that temperature control will be set when the print starts.</span>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Temperature Deadband') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: temperature_control_deadband">
<span class="help-inline">Allowabe drift on temperature control.</span>
<input type="text" class="input-block-level" data-bind="value: temp_ctr_deadband">
<span class="help-inline">Allowabe drift on temperature control. Set it to zero to disable.</span>
</div>
</div>
<!-- ko if: ($data.temperature_control_type() == "heater") -->
<!-- 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: temperature_control_max_temperature">
<span class="help-inline">Maximun temperature that the enclosure should reach, if this temperature is hit, the heater will be disabled.</span>
<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>
</div>
</div>
<!-- /ko -->
@@ -193,7 +193,7 @@
<div class="control-group">
<label class="control-label">{{ _('Set Temperature') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: alarm_set_temperature">
<input type="text" class="input-block-level" data-bind="value: alarm_set_temp">
<span class="help-inline">Set temperature that will trigger the event</span>
</div>
</div>
@@ -338,7 +338,7 @@
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtModel">{{ _('Sensor Type') }}</label>
<div class="controls">
<select data-bind="value: temperature_sensor_type">
<select data-bind="value: temp_sensor_type">
<option value="">Select Sensor</option>
<option value="11">DHT11</option>
<option value="22">DHT22</option>
@@ -354,7 +354,7 @@
<a href=" https://github.com/vitormhenrique/OctoPrint-Enclosure">github</a> page</span>
</div>
</div>
<!-- ko if: ($data.temperature_sensor_type() == "18b20") -->
<!-- ko if: ($data.temp_sensor_type() == "18b20") -->
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
<div class="controls">
@@ -371,7 +371,7 @@
</div>
</div>
<!-- /ko -->
<!-- ko if: ($data.temperature_sensor_type() == "si7021") || ($data.temperature_sensor_type() == "bme280") || ($data.temperature_sensor_type() == "tmp102") -->
<!-- ko if: ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "tmp102") -->
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
<div class="controls">
@@ -384,13 +384,13 @@
<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: temperature_sensor_address">
<input type="text" class="input-block-level" data-bind="value: temp_sensor_address">
<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.temperature_sensor_type() == "18b20") || ($data.temperature_sensor_type() == "si7021") || ($data.temperature_sensor_type() == "bme280") || ($data.temperature_sensor_type() == "tmp102") -->
<!-- ko ifnot: ($data.temp_sensor_type() == "18b20") || ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "tmp102") -->
<div class="control-group">
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
<div class="controls">
@@ -532,7 +532,7 @@
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: temperature_sensor_navbar"> {{ _('Show temperature on navbar') }}
<input type="checkbox" data-bind="checked: temp_sensor_navbar"> {{ _('Show temperature on navbar') }}
</label>
<span class="help-inline">Enable and disable temperature on navbar</span>
</div>

View File

@@ -1,74 +1,113 @@
<div class="row-fluid">
<!-- <pre data-bind="text: ko.toJSON($root.rpi_inputs_temperature_sensors(), null, 2)"></pre> -->
<table id="enclosure-table" class="table table-bordered table-hover">
<tbody>
<tr>
<th class="temperature_sensor"></th>
<th class="temperature_actual" title="{{ _('Current actual temperature as reported by your sensor') }}">{{ _('Temperature') }}</th>
<!-- ko if: ($root.hasAnySensorWithHumidity()) -->
<th class="humidity_actual" title="{{ _('Current humidity') }}">{{ _('Humidity') }}</th>
<!-- /ko -->
<th class="temperature_control">{{ _('Control') }}</th>
<th class="temperature_target" title="{{ _('Current target temperature') }}">{{ _('Target') }}</th>
</tr>
<!-- ko foreach: $root.rpi_inputs_temperature_sensors() -->
<tr>
<th class="temperature_sensor" data-bind="text: label, attr: {title: label, rowspan: $root.linkedTemperatureControl(index_id())().length}"></th>
<td class="temperature_actual" data-bind="html: temperature_sensor_temperature, attr: {title: temperature_sensor_temperature, rowspan: $root.linkedTemperatureControl(index_id())().length}"></td>
<!-- ko if: ($root.humidityCapableSensor(temperature_sensor_type)) -->
<td class="humidity_actual" data-bind="html: temperature_sensor_humidity, attr: {title: temperature_sensor_humidity, rowspan: $root.linkedTemperatureControl(index_id())().length}">
<span class="add-on">%</span>
</td>
<!-- /ko -->
<!-- ko if: ( $root.linkedTemperatureControl(index_id())().length > 0) -->
<!-- ko with: $root.linkedTemperatureControl(index_id())()[0] -->
<th class="temperature_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: temperature_control_new_temperature, valueUpdate: 'input', attr: {placeholder:$root.getCleanTemperature(temperature_control_set_temperature()), id: 'temp_control_' + index_id()}">
<span class="add-on" data-bind="visible: $parent.use_fahrenheit">&deg;F</span>
<span class="add-on" data-bind="visible: $parent.use_fahrenheit">&deg;C</span>
</div>
<div class="btn-group">
<button type="submit" data-bind="enable: $root.enableBtn()" 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()">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0)" data-bind="click: $root.turnOffHeater">{{ _('Off') }}</a>
</li>
</ul>
</div>
</form>
</td>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: ( !$root.linkedTemperatureControl(index_id())().length > 0) -->
<td class="temperature_control"></td>
<td class="temperature_target"></td>
<!-- /ko -->
</tr>
<!-- ko foreach: $root.linkedTemperatureControl(index_id())-->
<!-- ko ifnot: ($index() == 0) -->
<tr>
<th class="temperature_control" data-bind="html: label, attr: {title: label}"></th>
<td class="temperature_target">Set Temp</td>
</tr>
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
</tbody>
</table>
</div>
<!-- <pre data-bind="text: ko.toJSON($root.rpi_outputs(), null, 2)"></pre> -->
<!-- ko if: ($root.rpi_inputs_temperature_sensors().length > 0) -->
<div class="row-fluid">
<h4>Temperature</h4>
<!-- <pre data-bind="text: ko.toJSON($root.rpi_inputs_temperature_sensors(), null, 2)"></pre> -->
<table id="enclosure-table" class="table table-bordered table-hover">
<tbody>
<tr>
<th class="temperature_sensor"></th>
<th class="temperature_actual" title="{{ _('Current actual temperature as reported by your sensor') }}">{{ _('Temperature') }}</th>
<!-- ko if: ($root.hasAnySensorWithHumidity()) -->
<th class="humidity_actual" title="{{ _('Current humidity') }}">{{ _('Humidity') }}</th>
<!-- /ko -->
<!-- ko if: ($root.hasAnyTemperatureControl()) -->
<th class="temperature_control">{{ _('Control') }}</th>
<th class="temperature_target" title="{{ _('Current target temperature') }}">{{ _('Target') }}</th>
<!-- /ko -->
</tr>
<!-- ko foreach: $root.rpi_inputs_temperature_sensors() -->
<tr>
<th class="temperature_sensor" data-bind="text: label, attr: {title: label, rowspan: $root.linkedTemperatureControl(index_id())().length}"></th>
<td class="temperature_actual" data-bind="text: temp_sensor_temp, attr: {title: temp_sensor_temp, rowspan: $root.linkedTemperatureControl(index_id())().length}"></td>
<!-- ko if: ($root.humidityCapableSensor(temp_sensor_type())) -->
<td class="humidity_actual" data-bind="html: temp_sensor_humidity, attr: {title: temp_sensor_humidity, rowspan: $root.linkedTemperatureControl(index_id())().length}">
<span class="add-on">%</span>
</td>
<!-- /ko -->
<!-- ko if: ($root.hasAnySensorWithHumidity()) -->
<!-- ko ifnot: ($root.humidityCapableSensor(temp_sensor_type())) -->
<td>N/A</td>
<!-- /ko -->
<!-- /ko -->
<!-- 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>
<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()}">
<span class="add-on" data-bind="visible: $parent.use_fahrenheit">&deg;F</span>
<span class="add-on" data-bind="visible: $parent.use_fahrenheit">&deg;C</span>
</div>
<div class="btn-group">
<button type="submit" data-bind="enable: $root.enableBtn()" 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()">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0)" data-bind="click: $root.turnOffHeater">{{ _('Off') }}</a>
</li>
</ul>
</div>
</form>
</td>
<!-- /ko -->
<!-- /ko -->
<!-- ko if: ($root.hasAnyTemperatureControl()) -->
<!-- ko if: ( !$root.linkedTemperatureControl(index_id())().length > 0) -->
<td class="temperature_control"></td>
<td class="temperature_target"></td>
<!-- /ko -->
<!-- /ko -->
</tr>
<!-- ko if: ($root.hasAnyTemperatureControl()) -->
<!-- ko foreach: $root.linkedTemperatureControl(index_id())-->
<!-- ko ifnot: ($index() == 0) -->
<tr>
<th class="temperature_control" data-bind="html: label, attr: {title: label}"></th>
<td class="temperature_target">Set Temp</td>
</tr>
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
</tbody>
</table>
</div>
<!-- /ko -->
<!-- ko foreach: $root.rpi_outputs() -->
<!-- ko if: ($data.output_type() == "regular") -->
<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 if: ($data.gpio_status()) -->
<button data-bind="click: $root.handleIO" class="btn">Turn off</button>
<!-- /ko -->
<!-- ko ifnot: ($data.gpio_status()) -->
<button data-bind="click: $root.handleIO" class="btn">Turn on</button>
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->

View File

@@ -1,54 +1,20 @@
<div data-bind="foreach: settingsViewModel.settings.plugins.enclosure.temperature_reading">
<div data-bind="visible: isEnabled">
<h4>{{ _('Enclosure Temperature') }}</h4>
<table class="table table-bordered table-hover" style="table-layout: fixed; width: 100%; margin-top: 20px">
<tr>
<th style="width: 18%"></th>
<th style="width: 12%; text-align: right">{{ _('Actual') }}</th>
<th style="width: 35%">{{ _('Target') }}</th>
</tr>
<tr>
<th style="vertical-align: middle">{{ _('Enclosure') }}</th>
<td style="text-align: right; vertical-align: middle">
<span data-bind="html: $root.enclosureTemp"></span>
<span class="add-on" data-bind="visible: $data.use_fahrenheit">&deg;F</span>
<span class="add-on" data-bind="visible: !$data.use_fahrenheit()">&deg;C</span>
</td>
<td style="vertical-align: middle; overflow: visible">
<div data-bind="foreach: $root.settingsViewModel.settings.plugins.enclosure.temperature_control">
<div class="input-append" data-bind="visible: isEnabled">
<input type="text" class="input-mini text-right tempInput" id="enclosureSetTemp" data-bind="attr: {placeholder:$root.getCleanTemperature($root.requestEnclosureSetTemperature())}">
<span class="add-on" data-bind="visible: $parent.use_fahrenheit">&deg;F</span>
<span class="add-on" data-bind="visible: !$parent.use_fahrenheit()">&deg;C</span>
<div class="btn-group">
<button type="submit" data-bind="click: $root.setTemperature, enable: $root.enableBtn()" class="btn">{{ _('Set') }}</button>
<button class="btn dropdown-toggle" data-toggle="dropdown" data-bind="enable: $root.enableBtn()">
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="#" data-bind="click: $root.turnOffHeater">{{ _('Off') }}</a>
</li>
</ul>
</div>
</div>
</div>
</td>
</tr>
<tr data-bind="visible: $root.enclosureHumidity">
<th style="vertical-align: middle">{{ _('Humidity') }}</th>
<td style="text-align: right; vertical-align: middle">
<span data-bind="html: $root.enclosureHumidity"></span>
<span class="add-on">%</span>
</td>
<th></th>
</tr>
</table>
</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 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>
@@ -88,7 +54,7 @@
attr: {name: 'colorpicker', id: 'color_'+ $data.gpio_pin()} ,
click: $root.showColorPicker()">
</td>
<td style="width: 80%;align:left;border-top:0px;padding:0px">
<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>

View File

@@ -1,64 +1,64 @@
{% 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>
{% 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>