From c1047d020c0cd53df6baee5c5bf1fa5fbb8afad5 Mon Sep 17 00:00:00 2001 From: Vitor de Miranda Henrique Date: Thu, 22 Feb 2018 23:05:06 -0600 Subject: [PATCH] output working --- octoprint_enclosure/__init__.py | 233 ++++----- .../static/css/bootstrap-colorpicker.css | 458 +++++++++--------- .../static/css/bootstrap2-toggle.css | 85 ++++ octoprint_enclosure/static/css/enclosure.css | 96 ++-- .../static/js/bootstrap-colorpicker.min.js | 8 +- .../static/js/bootstrap2-toggle.js | 180 +++++++ octoprint_enclosure/static/js/enclosure.js | 172 ++++--- .../templates/enclosure_settings.jinja2 | 34 +- .../templates/enclosure_tab.jinja2 | 187 ++++--- .../templates/enclosure_tab_temp.html | 62 +-- octoprint_enclosure/templates/temp2.html | 128 ++--- 11 files changed, 989 insertions(+), 654 deletions(-) create mode 100755 octoprint_enclosure/static/css/bootstrap2-toggle.css create mode 100755 octoprint_enclosure/static/js/bootstrap2-toggle.js diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 4d47335..9d90c6f 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -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 diff --git a/octoprint_enclosure/static/css/bootstrap-colorpicker.css b/octoprint_enclosure/static/css/bootstrap-colorpicker.css index 2429962..26cb0de 100755 --- a/octoprint_enclosure/static/css/bootstrap-colorpicker.css +++ b/octoprint_enclosure/static/css/bootstrap-colorpicker.css @@ -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 */ \ No newline at end of file diff --git a/octoprint_enclosure/static/css/bootstrap2-toggle.css b/octoprint_enclosure/static/css/bootstrap2-toggle.css new file mode 100755 index 0000000..3f48927 --- /dev/null +++ b/octoprint_enclosure/static/css/bootstrap2-toggle.css @@ -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; } + diff --git a/octoprint_enclosure/static/css/enclosure.css b/octoprint_enclosure/static/css/enclosure.css index a7c0ce4..8e090c4 100644 --- a/octoprint_enclosure/static/css/enclosure.css +++ b/octoprint_enclosure/static/css/enclosure.css @@ -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; +} + + diff --git a/octoprint_enclosure/static/js/bootstrap-colorpicker.min.js b/octoprint_enclosure/static/js/bootstrap-colorpicker.min.js index 2cec749..7cd35b8 100755 --- a/octoprint_enclosure/static/js/bootstrap-colorpicker.min.js +++ b/octoprint_enclosure/static/js/bootstrap-colorpicker.min.js @@ -1,5 +1,5 @@ -/*! - * Bootstrap Colorpicker v2.5.1 - * https://itsjavi.com/bootstrap-colorpicker/ - */ +/*! + * Bootstrap Colorpicker v2.5.1 + * https://itsjavi.com/bootstrap-colorpicker/ + */ !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):jQuery&&!jQuery.fn.colorpicker&&b(jQuery)}(this,function(a){"use strict";var b=function(c,d,e,f,g){this.fallbackValue=e?e&&"undefined"!=typeof e.h?e:this.value={h:0,s:0,b:0,a:1}:null,this.fallbackFormat=f?f:"rgba",this.hexNumberSignPrefix=g===!0,this.value=this.fallbackValue,this.origFormat=null,this.predefinedColors=d?d:{},this.colors=a.extend({},b.webColors,this.predefinedColors),c&&("undefined"!=typeof c.h?this.value=c:this.setColor(String(c))),this.value||(this.value={h:0,s:0,b:0,a:1})};b.webColors={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgrey:"d3d3d3",lightgreen:"90ee90",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"778899",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"00ff00",limegreen:"32cd32",linen:"faf0e6",magenta:"ff00ff",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370d8",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32",transparent:"transparent"},b.prototype={constructor:b,colors:{},predefinedColors:{},getValue:function(){return this.value},setValue:function(a){this.value=a},_sanitizeNumber:function(a){return"number"==typeof a?a:isNaN(a)||null===a||""===a||void 0===a?1:""===a?0:"undefined"!=typeof a.toLowerCase?(a.match(/^\./)&&(a="0"+a),Math.ceil(100*parseFloat(a))/100):1},isTransparent:function(a){return!(!a||!("string"==typeof a||a instanceof String))&&(a=a.toLowerCase().trim(),"transparent"===a||a.match(/#?00000000/)||a.match(/(rgba|hsla)\(0,0,0,0?\.?0\)/))},rgbaIsTransparent:function(a){return 0===a.r&&0===a.g&&0===a.b&&0===a.a},setColor:function(a){if(a=a.toLowerCase().trim()){if(this.isTransparent(a))return this.value={h:0,s:0,b:0,a:0},!0;var b=this.parse(a);b?(this.value=this.value={h:b.h,s:b.s,b:b.b,a:b.a},this.origFormat||(this.origFormat=b.format)):this.fallbackValue&&(this.value=this.fallbackValue)}return!1},setHue:function(a){this.value.h=1-a},setSaturation:function(a){this.value.s=a},setBrightness:function(a){this.value.b=1-a},setAlpha:function(a){this.value.a=Math.round(parseInt(100*(1-a),10)/100*100)/100},toRGB:function(a,b,c,d){0===arguments.length&&(a=this.value.h,b=this.value.s,c=this.value.b,d=this.value.a),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-Math.abs(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],{r:Math.round(255*e),g:Math.round(255*f),b:Math.round(255*g),a:d}},toHex:function(a,b,c,d){0===arguments.length&&(a=this.value.h,b=this.value.s,c=this.value.b,d=this.value.a);var e=this.toRGB(a,b,c,d);if(this.rgbaIsTransparent(e))return"transparent";var f=(this.hexNumberSignPrefix?"#":"")+((1<<24)+(parseInt(e.r)<<16)+(parseInt(e.g)<<8)+parseInt(e.b)).toString(16).slice(1);return f},toHSL:function(a,b,c,d){0===arguments.length&&(a=this.value.h,b=this.value.s,c=this.value.b,d=this.value.a);var e=a,f=(2-b)*c,g=b*c;return g/=f>0&&f<=1?f:2-f,f/=2,g>1&&(g=1),{h:isNaN(e)?0:e,s:isNaN(g)?0:g,l:isNaN(f)?0:f,a:isNaN(d)?0:d}},toAlias:function(a,b,c,d){var e,f=0===arguments.length?this.toHex():this.toHex(a,b,c,d),g="alias"===this.origFormat?f:this.toString(this.origFormat,!1);for(var h in this.colors)if(e=this.colors[h].toLowerCase().trim(),e===f||e===g)return h;return!1},RGBtoHSB:function(a,b,c,d){a/=255,b/=255,c/=255;var e,f,g,h;return g=Math.max(a,b,c),h=g-Math.min(a,b,c),e=0===h?null:g===a?(b-c)/h:g===b?(c-a)/h+2:(a-b)/h+4,e=(e+360)%6*60/360,f=0===h?0:h/g,{h:this._sanitizeNumber(e),s:f,b:g,a:this._sanitizeNumber(d)}},HueToRGB:function(a,b,c){return c<0?c+=1:c>1&&(c-=1),6*c<1?a+(b-a)*c*6:2*c<1?b:3*c<2?a+(b-a)*(2/3-c)*6:a},HSLtoRGB:function(a,b,c,d){b<0&&(b=0);var e;e=c<=.5?c*(1+b):c+b-c*b;var f=2*c-e,g=a+1/3,h=a,i=a-1/3,j=Math.round(255*this.HueToRGB(f,e,g)),k=Math.round(255*this.HueToRGB(f,e,h)),l=Math.round(255*this.HueToRGB(f,e,i));return[j,k,l,this._sanitizeNumber(d)]},parse:function(b){if(0===arguments.length)return!1;var c,d,e=this,f=!1,g="undefined"!=typeof this.colors[b];return g&&(b=this.colors[b].toLowerCase().trim()),a.each(this.stringParsers,function(a,h){var i=h.re.exec(b);return c=i&&h.parse.apply(e,[i]),!c||(f={},d=g?"alias":h.format?h.format:e.getValidFallbackFormat(),f=d.match(/hsla?/)?e.RGBtoHSB.apply(e,e.HSLtoRGB.apply(e,c)):e.RGBtoHSB.apply(e,c),f instanceof Object&&(f.format=d),!1)}),f},getValidFallbackFormat:function(){var a=["rgba","rgb","hex","hsla","hsl"];return this.origFormat&&a.indexOf(this.origFormat)!==-1?this.origFormat:this.fallbackFormat&&a.indexOf(this.fallbackFormat)!==-1?this.fallbackFormat:"rgba"},toString:function(a,c){a=a||this.origFormat||this.fallbackFormat,c=c||!1;var d=!1;switch(a){case"rgb":return d=this.toRGB(),this.rgbaIsTransparent(d)?"transparent":"rgb("+d.r+","+d.g+","+d.b+")";case"rgba":return d=this.toRGB(),"rgba("+d.r+","+d.g+","+d.b+","+d.a+")";case"hsl":return d=this.toHSL(),"hsl("+Math.round(360*d.h)+","+Math.round(100*d.s)+"%,"+Math.round(100*d.l)+"%)";case"hsla":return d=this.toHSL(),"hsla("+Math.round(360*d.h)+","+Math.round(100*d.s)+"%,"+Math.round(100*d.l)+"%,"+d.a+")";case"hex":return this.toHex();case"alias":return d=this.toAlias(),d===!1?this.toString(this.getValidFallbackFormat()):c&&!(d in b.webColors)&&d in this.predefinedColors?this.predefinedColors[d]:d;default:return d}},stringParsers:[{re:/rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/,format:"rgb",parse:function(a){return[a[1],a[2],a[3],1]}},{re:/rgb\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/,format:"rgb",parse:function(a){return[2.55*a[1],2.55*a[2],2.55*a[3],1]}},{re:/rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/,format:"rgba",parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/,format:"rgba",parse:function(a){return[2.55*a[1],2.55*a[2],2.55*a[3],a[4]]}},{re:/hsl\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/,format:"hsl",parse:function(a){return[a[1]/360,a[2]/100,a[3]/100,a[4]]}},{re:/hsla\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/,format:"hsla",parse:function(a){return[a[1]/360,a[2]/100,a[3]/100,a[4]]}},{re:/#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,format:"hex",parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16),1]}},{re:/#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,format:"hex",parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16),1]}}],colorNameToHex:function(a){return"undefined"!=typeof this.colors[a.toLowerCase()]&&this.colors[a.toLowerCase()]}};var c={horizontal:!1,inline:!1,color:!1,format:!1,input:"input",container:!1,component:".add-on, .input-group-addon",fallbackColor:!1,fallbackFormat:"hex",hexNumberSignPrefix:!0,sliders:{saturation:{maxLeft:100,maxTop:100,callLeft:"setSaturation",callTop:"setBrightness"},hue:{maxLeft:0,maxTop:100,callLeft:!1,callTop:"setHue"},alpha:{maxLeft:0,maxTop:100,callLeft:!1,callTop:"setAlpha"}},slidersHorz:{saturation:{maxLeft:100,maxTop:100,callLeft:"setSaturation",callTop:"setBrightness"},hue:{maxLeft:100,maxTop:0,callLeft:"setHue",callTop:!1},alpha:{maxLeft:100,maxTop:0,callLeft:"setAlpha",callTop:!1}},template:'