From 15451eced8c5e8ee40cb7982ca44aa89dbac57c7 Mon Sep 17 00:00:00 2001 From: Marian Date: Sun, 3 Feb 2019 19:37:12 +0100 Subject: [PATCH 1/6] Use temperature offsets when applying preheat implements #17 --- octoprint_preheat/__init__.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/octoprint_preheat/__init__.py b/octoprint_preheat/__init__.py index ec35f6f..7fbbc71 100644 --- a/octoprint_preheat/__init__.py +++ b/octoprint_preheat/__init__.py @@ -129,12 +129,18 @@ def preheat(self): if not self._printer.is_operational() or self._printer.is_printing(): raise PreheatError("Can't set the temperature because the printer is not ready.") + offsets = self._printer.get_current_data()["offsets"] + try: temperatures = self.get_temperatures() for key in temperatures: - self._logger.info("Preheating " + key + " to " + str(temperatures[key])) - self._printer.set_temperature(key, temperatures[key]) + target = temperatures[key] + if key in offsets: + target += offsets[key] + + self._logger.info("Preheating " + key + " to " + str(target)) + self._printer.set_temperature(key, target) except PreheatError as error: if not self.apply_fallback_temperature(): raise PreheatError(str(error.message) + "\n" + "You can configure fallback temperatures in the plugin settings for this case.") From 95a963d01bdcc56cd239cb093dfb0988d02b79ef Mon Sep 17 00:00:00 2001 From: Marian Date: Sun, 3 Feb 2019 21:46:56 +0100 Subject: [PATCH 2/6] Apply temperature offsets in a separate method --- octoprint_preheat/__init__.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/octoprint_preheat/__init__.py b/octoprint_preheat/__init__.py index 7fbbc71..832bb97 100644 --- a/octoprint_preheat/__init__.py +++ b/octoprint_preheat/__init__.py @@ -124,23 +124,28 @@ def get_temperatures(self): if len(temperatures) == 0: raise PreheatError("Could not find a preheat command in the gcode file.") return temperatures - + + def apply_offsets(self, temperatures): + offsets = self._printer.get_current_data()["offsets"] + for tool in temperatures: + if tool in offsets: + temperatures[tool] += offsets[tool] + def preheat(self): if not self._printer.is_operational() or self._printer.is_printing(): raise PreheatError("Can't set the temperature because the printer is not ready.") - offsets = self._printer.get_current_data()["offsets"] - try: temperatures = self.get_temperatures() + self.apply_offsets(temperatures) - for key in temperatures: - target = temperatures[key] - if key in offsets: - target += offsets[key] + self._logger.info("Preheating bed to " + str(target) + " and waiting.") + self._printer.commands(["M190 S{}".format(target)]) - self._logger.info("Preheating " + key + " to " + str(target)) - self._printer.set_temperature(key, target) + for tool in temperatures: + self._logger.info("Preheating " + tool + " to " + str(target) + ".") + self._printer.set_temperature(tool, target) + except PreheatError as error: if not self.apply_fallback_temperature(): raise PreheatError(str(error.message) + "\n" + "You can configure fallback temperatures in the plugin settings for this case.") From db9735592ffd7d481ec7d4bf635391a60cbfd323 Mon Sep 17 00:00:00 2001 From: Marian Date: Sun, 3 Feb 2019 22:39:34 +0100 Subject: [PATCH 3/6] Implement sequenced preheating where the bed is preheated first #implements #12 --- octoprint_preheat/__init__.py | 61 +++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/octoprint_preheat/__init__.py b/octoprint_preheat/__init__.py index 832bb97..8006e75 100644 --- a/octoprint_preheat/__init__.py +++ b/octoprint_preheat/__init__.py @@ -8,6 +8,8 @@ from octoprint.util.comm import strip_comment import flask +import time +from threading import Thread class PreheatError(Exception): def __init__(self, message): @@ -123,26 +125,65 @@ def get_temperatures(self): if len(temperatures) == 0: raise PreheatError("Could not find a preheat command in the gcode file.") - return temperatures - - def apply_offsets(self, temperatures): + offsets = self._printer.get_current_data()["offsets"] for tool in temperatures: if tool in offsets: temperatures[tool] += offsets[tool] + + return temperatures - def preheat(self): + def check_state(self): if not self._printer.is_operational() or self._printer.is_printing(): raise PreheatError("Can't set the temperature because the printer is not ready.") + + def start_preheat_sequence(self): + self.check_state() + + preheat_temperatures = self.get_temperatures() + + if "bed" not in preheat_temperatures: + self.preheat() + return + + bed_temp = preheat_temperatures["bed"] + self._logger.info("Preheating bed to " + str(bed_temp) + " and waiting.") + self._printer.set_temperature("bed", bed_temp) + + thread = Thread(target = self.wait_for_bed_and_preheat, args = (preheat_temperatures, )) + thread.start() + + def wait_for_bed_and_preheat(self, preheat_temperatures): + current_temperatures = self._printer.get_current_temperatures() + + initial_targets = {tool: current_temperatures[tool]["target"] for tool in preheat_temperatures.keys()} + initial_targets["bed"] = preheat_temperatures["bed"] + + while (True): + time.sleep(0.4) + + current_temperatures = self._printer.get_current_temperatures() + for tool in preheat_temperatures.keys(): + if current_temperatures[tool]["target"] != initial_targets[tool]: + self._logger.info("Preheating cancelled because the temperature was changed manually.") + return + + if abs(current_temperatures["bed"]["actual"] - current_temperatures["bed"]["target"]) < 4: + break try: - temperatures = self.get_temperatures() - self.apply_offsets(temperatures) - - self._logger.info("Preheating bed to " + str(target) + " and waiting.") - self._printer.commands(["M190 S{}".format(target)]) + self.preheat(preheat_temperatures) + except PreheatError as error: + self._logger.info("Preheat error: " + str(error.message)) + + def preheat(self, temperatures = None): + self.check_state() - for tool in temperatures: + try: + if temperatures is None: + temperatures = self.get_temperatures() + + for tool, target in temperatures.iteritems(): self._logger.info("Preheating " + tool + " to " + str(target) + ".") self._printer.set_temperature(tool, target) From 44032639b0b662b53c079d5283880c6de4eb0e99 Mon Sep 17 00:00:00 2001 From: Marian Date: Sun, 3 Feb 2019 23:05:14 +0100 Subject: [PATCH 4/6] Add an option to switch between instant and sequenced preheating --- octoprint_preheat/__init__.py | 8 ++++++-- octoprint_preheat/templates/preheat_settings.jinja2 | 13 ++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/octoprint_preheat/__init__.py b/octoprint_preheat/__init__.py index 8006e75..4a75384 100644 --- a/octoprint_preheat/__init__.py +++ b/octoprint_preheat/__init__.py @@ -24,7 +24,8 @@ def get_settings_defaults(self): return dict(enable_tool = True, enable_bed = True, fallback_tool = 0, - fallback_bed = 0) + fallback_bed = 0, + wait_for_bed = False) def get_template_configs(self): return [ @@ -197,7 +198,10 @@ def on_api_command(self, command, data): if current_user.is_anonymous(): return "Insufficient rights", 403 try: - self.preheat() + if self._settings.get_boolean(["wait_for_bed"]): + self.start_preheat_sequence() + else: + self.preheat() except PreheatError as error: self._logger.info("Preheat error: " + str(error.message)) return str(error.message), 405 diff --git a/octoprint_preheat/templates/preheat_settings.jinja2 b/octoprint_preheat/templates/preheat_settings.jinja2 index f4c439e..18f9826 100644 --- a/octoprint_preheat/templates/preheat_settings.jinja2 +++ b/octoprint_preheat/templates/preheat_settings.jinja2 @@ -1,6 +1,6 @@
- Enable preheating + Enable Preheating
@@ -31,5 +31,16 @@ °
+

+ + Sequenced Preheating +
+ Preheat bed first, then heat printheads once the bed has reached it's target temperature. + If this option is disabled, the bed and printheads are heated right away. + If you don't have a heated bed, this option makes no difference. +
+
+ +
\ No newline at end of file From 67a319483912e9a7c538c212b601a1d99b1a219a Mon Sep 17 00:00:00 2001 From: Marian Date: Sun, 3 Feb 2019 23:17:05 +0100 Subject: [PATCH 5/6] Make fallback temperatures work with the new preheat logic --- octoprint_preheat/__init__.py | 65 ++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/octoprint_preheat/__init__.py b/octoprint_preheat/__init__.py index 4a75384..dd82710 100644 --- a/octoprint_preheat/__init__.py +++ b/octoprint_preheat/__init__.py @@ -26,22 +26,26 @@ def get_settings_defaults(self): fallback_tool = 0, fallback_bed = 0, wait_for_bed = False) + def get_template_configs(self): return [ dict(type="settings", custom_bindings = False) ] + def get_assets(self): return dict( js = ["js/preheat.js"], css = ["css/preheat.css"] ) + def get_api_commands(self): return dict( preheat = [] ) + def parse_line(self, line): line = strip_comment(line) @@ -61,30 +65,29 @@ def parse_line(self, line): tool = "tool" + item[1:].strip() return tool, temperature + - def apply_fallback_temperature(self): - fallback_successful = False + def get_fallback_temperature(self): enable_bed = self._settings.get_boolean(["enable_bed"]) enable_tool = self._settings.get_boolean(["enable_tool"]) fallback_tool = self._settings.get_float(["fallback_tool"]) fallback_bed = self._settings.get_float(["fallback_bed"]) printer_profile = self._printer._printerProfileManager.get_current_or_default() + + result = dict() if enable_bed and fallback_bed > 0 and printer_profile["heatedBed"]: - self._logger.info("Using fallback temperature, preheating bed to " + str(fallback_bed)) - self._printer.set_temperature("bed", fallback_bed) - fallback_successful = True + result["bed"] = fallback_bed if enable_tool and fallback_tool > 0: extruder_count = printer_profile["extruder"]["count"] for i in range(extruder_count): tool = "tool" + str(i) - self._logger.info("Using fallback temperature, preheating " + tool + " to " + str(fallback_tool)) - self._printer.set_temperature(tool, fallback_tool) - fallback_successful = True + result[tool] = fallback_tool - return fallback_successful + return result + def get_temperatures(self): printer = self._printer @@ -125,7 +128,12 @@ def get_temperatures(self): self._logger.exception("Something went wrong while trying to read the preheat temperature from {}".format(path_on_disk)) if len(temperatures) == 0: - raise PreheatError("Could not find a preheat command in the gcode file.") + temperatures = self.get_fallback_temperature() + + if len(temperatures) == 0: + raise PreheatError("Could not find any preheat commands in the gcode file. You can configure fallback temperatures for this case.") + else: + self._logger.info("Could not find any preheat commands in the gcode file, using fallback temperatures.") offsets = self._printer.get_current_data()["offsets"] for tool in temperatures: @@ -134,9 +142,11 @@ def get_temperatures(self): return temperatures + def check_state(self): if not self._printer.is_operational() or self._printer.is_printing(): raise PreheatError("Can't set the temperature because the printer is not ready.") + def start_preheat_sequence(self): self.check_state() @@ -154,6 +164,7 @@ def start_preheat_sequence(self): thread = Thread(target = self.wait_for_bed_and_preheat, args = (preheat_temperatures, )) thread.start() + def wait_for_bed_and_preheat(self, preheat_temperatures): current_temperatures = self._printer.get_current_temperatures() @@ -173,24 +184,26 @@ def wait_for_bed_and_preheat(self, preheat_temperatures): break try: - self.preheat(preheat_temperatures) + self.preheat_all(preheat_temperatures) except PreheatError as error: self._logger.info("Preheat error: " + str(error.message)) - def preheat(self, temperatures = None): + + def preheat_all(self, temperatures = None): self.check_state() - try: - if temperatures is None: - temperatures = self.get_temperatures() - - for tool, target in temperatures.iteritems(): - self._logger.info("Preheating " + tool + " to " + str(target) + ".") - self._printer.set_temperature(tool, target) - - except PreheatError as error: - if not self.apply_fallback_temperature(): - raise PreheatError(str(error.message) + "\n" + "You can configure fallback temperatures in the plugin settings for this case.") + if temperatures is None: + temperatures = self.get_temperatures() + + for tool, target in temperatures.iteritems(): + self._logger.info("Preheating " + tool + " to " + str(target) + ".") + self._printer.set_temperature(tool, target) + + def preheat(self): + if self._settings.get_boolean(["wait_for_bed"]): + self.start_preheat_sequence() + else: + self.preheat_all() def on_api_command(self, command, data): import flask @@ -198,13 +211,11 @@ def on_api_command(self, command, data): if current_user.is_anonymous(): return "Insufficient rights", 403 try: - if self._settings.get_boolean(["wait_for_bed"]): - self.start_preheat_sequence() - else: - self.preheat() + self.preheat() except PreheatError as error: self._logger.info("Preheat error: " + str(error.message)) return str(error.message), 405 + def get_update_information(self, *args, **kwargs): return dict( From 59d33e0459a61ca7ab6a0684d0fb1660ff9b9a7c Mon Sep 17 00:00:00 2001 From: Marian Date: Sun, 3 Feb 2019 23:55:01 +0100 Subject: [PATCH 6/6] Bump version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3876442..a553a70 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ plugin_name = "Preheat" # The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module -plugin_version = "0.2.0" +plugin_version = "0.3.0" # The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin # module