From e954dbefc086e16a71c51968bad1f2e675530f40 Mon Sep 17 00:00:00 2001 From: Vitor de Miranda Henrique Date: Fri, 15 Jun 2018 13:53:00 -0500 Subject: [PATCH] dev new features --- octoprint_enclosure/__init__.py | 115 +++++++++++++++--- octoprint_enclosure/static/js/enclosure.js | 7 +- .../templates/enclosure_settings.jinja2 | 88 ++++++++------ 3 files changed, 157 insertions(+), 53 deletions(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 683d4d6..72e108e 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -118,16 +118,29 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, self.print_complete = False def get_settings_version(self): - return 4 + return 6 def on_settings_migrate(self, target, current=None): - self._logger.warn("######### settings not compatible #########") - self._logger.warn("######### current settings version %s target settings version %s #########", - current, target) - self._settings.set(["rpi_outputs"], []) - self._settings.set(["rpi_inputs"], []) - self.rpi_outputs = self._settings.get(["rpi_outputs"]) - self.rpi_inputs = self._settings.get(["rpi_inputs"]) + self._logger.warn("######### current settings version %s target settings version %s #########", current, target) + + if current >= 4 and target == 6: + self._logger.warn( + "######### migrating settings to v6 #########") + for rpi_output in old_outputs: + if 'shutdown_on_failed' not in rpi_output: + rpi_output['shutdown_on_failed'] = False + if 'shutdown_on_failed' not in rpi_output: + if current == 4 and target == 5: + self._logger.warn("######### migrating settings from v4 to v5 #########") + old_outputs = self._settings.get(["rpi_outputs"]) + for rpi_output in old_outputs: + rpi_output['shutdown_on_failed'] = False + self._settings.set(["rpi_outputs"], old_outputs) + else: + self._logger.warn("######### settings not compatible #########") + self._settings.set(["rpi_outputs"], []) + self._settings.set(["rpi_inputs"], []) + self.rpi_inputs = self._settings.get(["rpi_inputs"]) # ~~ Blueprintplugin mixin @octoprint.plugin.BlueprintPlugin.route("/setEnclosureTempHum", methods=["GET"]) @@ -175,6 +188,19 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, self.write_gpio(self.to_int(rpi_output['gpio_pin']), val) return flask.jsonify(success=True) + @octoprint.plugin.BlueprintPlugin.route("/sendShellCommand", methods=["GET"]) + def send_shell_command(self): + output_index = self.to_int(flask.request.values["index_id"]) + + rpi_output = [r_out for r_out in self.rpi_outputs if self.to_int( + r_out['index_id']) == output_index].pop() + + if rpi_output: + command = rpi_output['shell_script'] + self.shell_command(command) + return flask.jsonify(success=True) + + @octoprint.plugin.BlueprintPlugin.route("/setAutoStartUp", methods=["GET"]) def set_auto_startup(self): index = flask.request.values["index_id"] @@ -262,6 +288,16 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, return flask.jsonify(success=True) + def shell_command(self, command): + try: + stdout = (Popen(command, shell=True, stdout=PIPE).stdout).read() + self._plugin_manager.send_plugin_message( + self._identifier, dict(is_msg=True, msg=stdout, msg_type="success")) + except Exception as ex: + self.log_error(ex) + self._plugin_manager.send_plugin_message( + self._identifier, dict(is_msg=True, msg="Could not execute shell script", msg_type="error")) + def send_neopixel_command(self, led_pin, led_count, led_brightness, red, green, blue, address, neopixel_dirrect, index_id, queue_id=None): """Send neopixel command @@ -790,7 +826,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, tempstr + " as pin numbers. Please update GPIO accordingly!" self._logger.info(warn_msg) self._plugin_manager.send_plugin_message( - self._identifier, dict(isMsg=True, msg=warn_msg)) + self._identifier, dict(is_msg=True, msg=warn_msg, msg_type="error")) GPIO.setwarnings(False) except Exception as ex: self.log_error(ex) @@ -978,6 +1014,9 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, str(rpi_input['label']) + \ ". Sending GCODE command" self.send_notification(msg) + if rpi_output['output_type'] == 'shell_output': + command = rpi_output['shell_script'] + self.shell_command(command) except Exception as ex: self.log_error(ex) pass @@ -1007,11 +1046,18 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, self._printer.cancel_print() elif rpi_input['printer_action'] == 'toggle': self._logger.info("Printer action toggle.") + if self._printer.is_operational(): + self._printer.toggle_pause_print() + else: + self._printer.connect() + elif rpi_input['printer_action'] == 'start': + self._printer.start_print() + elif rpi_input['printer_action'] == 'toggle_job': if self._printer.is_operational(): if self._printer.is_printing(): - self._printer.pause_print() - elif self._printer.is_paused(): - self._printer.resume_print() + self._printer.cancel_print() + elif self._printer.is_ready(): + self._printer.start_print() else: self._printer.connect() elif rpi_input['printer_action'] == 'stop_temp_hum_control': @@ -1157,8 +1203,6 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, delay_seconds = self.to_float(shutdown_time) self.schedule_auto_shutdown_outputs( rpi_output, delay_seconds) - if rpi_output['output_type'] == 'temp_hum_control': - rpi_output['temp_ctr_set_value'] = 0 self.run_tasks() self.update_ui() @@ -1198,6 +1242,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, if (rpi_output['output_type'] == 'neopixel_indirect' or rpi_output['output_type'] == 'neopixel_direct'): self.add_neopixel_output_to_queue( rpi_output, shutdown_delay_seconds, 0, 0, 0, sufix) + if rpi_output['output_type'] == 'temp_hum_control': + value = 0 + self.add_temperature_output_temperature_queue( + delay_seconds, rpi_output, value, sufix) if self._settings.get(["debug"]) is True: self._logger.info("Events scheduled to run %s", self.event_queue) @@ -1240,7 +1288,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, self.add_neopixel_output_to_queue( rpi_output, delay_seconds, red, green, blue, sufix) if rpi_output['output_type'] == 'temp_hum_control': - rpi_output['temp_ctr_set_value'] = rpi_output['temp_ctr_default_value'] + value = rpi_output['temp_ctr_default_value'] + self.add_temperature_output_temperature_queue(delay_seconds, rpi_output, value, sufix) if self._settings.get(["debug"]) is True: self._logger.info("Events scheduled to run %s", self.event_queue) @@ -1325,6 +1374,42 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, self.event_queue.append(dict(queue_id=queue_id, thread=thread)) + def add_temperature_output_temperature_queue(self, delay_seconds, rpi_output, value, sufix): + queue_id = '{0!s}_{1!s}'.format(rpi_output['index_id'], sufix) + if self._settings.get(["debug"]) is True: + self._logger.info("Scheduling temperature control id %s on %s delay_seconds", queue_id, delay_seconds) + + thread = threading.Timer(delay_seconds, + self.write_temperature_to_output, + args=[self.to_int(rpi_output['index_id']), value, queue_id]) + + self.event_queue.append(dict(queue_id=queue_id, thread=thread)) + + def write_temperature_to_output(self, rpi_output_index, value, queue_id=None): + try: + rpi_output = [r_out for r_out in self.rpi_outputs if self.to_int( + r_out['index_id']) == rpi_output_index].pop() + + if rpi_output['output_type'] == 'temp_hum_control': + rpi_output['temp_ctr_set_value'] = value + + if self._settings.get(["debug"]) is True: + if queue_id is not None: + self._logger.info("Runing scheduled queue id %s", queue_id) + self._logger.info( + "Setting temperature to output index: %s value %s", rpi_output['index_id'], value) + + self.update_ui() + if queue_id is not None: + self.stop_queue_item(queue_id) + + except Exception as ex: + template = "An exception of type {0} occurred on {1} when writing on pin {2}. Arguments:\n{3!r}" + message = template.format( + type(ex).__name__, inspect.currentframe().f_code.co_name, gpio, ex.args) + self._logger.warn(message) + pass + def get_startup_delay_from_output(self, rpi_output): start_up_time = rpi_output['startup_time'] if self.is_hour(start_up_time): diff --git a/octoprint_enclosure/static/js/enclosure.js b/octoprint_enclosure/static/js/enclosure.js index 36c391a..14488e0 100644 --- a/octoprint_enclosure/static/js/enclosure.js +++ b/octoprint_enclosure/static/js/enclosure.js @@ -21,7 +21,7 @@ $(function () { self.settings_possible_outputs = ko.pureComputed(function () { return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs(), function (item) { - return ((item.output_type() === "regular" && !item.toggle_timer()) || item.output_type() === "gcode_output"); + return ((item.output_type() === "regular" && !item.toggle_timer()) || item.output_type() === "gcode_output" || item.output_type() === "shell_output"); }); }); @@ -226,11 +226,11 @@ $(function () { }) } - if (data.isMsg) { + if (data.is_msg) { new PNotify({ title: "Enclosure", text: data.msg, - type: "error" + type: data.msg_type }); } }; @@ -348,6 +348,7 @@ $(function () { index_id: ko.observable(nextIndex), label: ko.observable("Ouput " + nextIndex), output_type: ko.observable("regular"), + shell_script: ko.observable(""), gpio_pin: ko.observable(0), gpio_status: ko.observable(false), hide_btn_ui: ko.observable(false), diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index 1be738a..1e0cc68 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -53,6 +53,12 @@ +
+ +
@@ -70,6 +76,15 @@ Id used for API control
+ +
+ +
+ + Shell script to be executed +
+
+
@@ -88,45 +103,45 @@
- -
-
- - Link PWM ouput to temperature. PWM output will be interpolated between the point from duty A, temperature A -> duty B, temperature B. - This output will automatomatically start when a print starts and will default to the default duty cycle when print is complete. - -
+
+
+ + Link PWM ouput to temperature. PWM output will be interpolated between the point from duty A, temperature A -> duty + B, temperature B. This output will automatomatically start when a print starts and will default to the default + duty cycle when print is complete. +
- +
+ -
- -
- -
+
+ +
+
-
- -
- -
+
+
+ +
+
-
- -
- -
+
+
+ +
+
-
- -
- -
+
+
+ +
+
+
@@ -212,15 +227,16 @@ Time delay in secconds to turn on GPIO when print starts OR exact time that the event should happen, note that events will only be scheduled after a print starts, time should be formated as HH:MM on a 24 hours format, don't forget to check timezone of your raspberry pi. - Attention - Hour schedule does not work with Link PWM to Temperature option + Attention + Hour schedule does not work with + Link PWM to Temperature option
- +
- +