From bfe5bc179c726b6363167842897eebb739a76fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Tue, 22 Aug 2017 11:32:47 +0200 Subject: [PATCH] New hook octoprint.comm.protocol.temperatures.received Allows preprocessing/sanitizing temperatures as received from the printer. Workaround for printers that occasionally report garbage temperature data, e.g. #2050 --- docs/plugins/hooks.rst | 26 ++++++++++++++++++++++++++ src/octoprint/util/comm.py | 10 ++++++++++ 2 files changed, 36 insertions(+) diff --git a/docs/plugins/hooks.rst b/docs/plugins/hooks.rst index 5e5b9c8f..a53a4781 100644 --- a/docs/plugins/hooks.rst +++ b/docs/plugins/hooks.rst @@ -555,6 +555,32 @@ octoprint.comm.protocol.scripts :return: A 2-tuple in the form ``(prefix, postfix)`` or None :rtype: tuple or None +.. _sec-plugins-hook-comm-protocol-temperatures-received: + +octoprint.comm.protocol.temperatures.received +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. py:function:: protocol_temperatures_received_hook(comm_instance, parsed_temperatures, *args, **kwargs) + + Get the parsed temperatures returned by the printer, allowing handlers to modify them prior to handing them off + to the system. Handlers are expected to either return ``parsed_temperatures`` as-is or a modified copy thereof. + + ``parsed_temperatures`` is a dictionary mapping from tool/bed identifier (``B``, ``T0``, ``T1``) to a 2-tuple of + actual and target temperature, e.g. ``{'B': (45.2, 50.0), 'T0': (178.9, 210.0), 'T1': (21.3, 0.0)}``. + + This hook can be useful in cases where a printer e.g. is prone to returning garbage data from time to time, allowing + additional sanity checking to be applied and invalid values to be filtered out. If a handler returns an empty + dictionary or ``None``, no further processing will take place. + + **Example** + + The following example shows how to filter out actual temperatures that are outside a sane range of 1°C to 300°C. + + .. onlineinclude:: https://raw.githubusercontent.com/OctoPrint/Plugin-Examples/master/sanitize_temperatures.py + :linenos: + :tab-width: 4 + :caption: `sanitize_temperatures.py `_ + .. _sec-plugins-hook-comm-transport-serial-factory: octoprint.comm.transport.serial.factory diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index cdad5130..ecd0a74e 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -441,6 +441,8 @@ class MachineCom(object): self._gcodescript_hooks = self._pluginManager.get_hooks("octoprint.comm.protocol.scripts") self._serial_factory_hooks = self._pluginManager.get_hooks("octoprint.comm.transport.serial.factory") + self._temperature_hooks = self._pluginManager.get_hooks("octoprint.comm.protocol.temperatures.received") + # SD status data self._sdEnabled = settings().getBoolean(["feature", "sdSupport"]) self._sdAvailable = False @@ -1129,6 +1131,14 @@ class MachineCom(object): current_tool = self._currentTool if self._currentTool is not None else 0 maxToolNum, parsedTemps = parse_temperature_line(line, current_tool) + for name, hook in self._temperature_hooks.items(): + try: + parsedTemps = hook(self, parsedTemps) + if parsedTemps is None or not parsedTemps: + return + except: + self._logger.exception("Error while processing temperatures in {}, skipping".format(name)) + if "T0" in parsedTemps.keys(): for n in range(maxToolNum + 1): tool = "T%d" % n