From 03b2a6e7ae0c6c98b470c44a76f1ec3afd5763c4 Mon Sep 17 00:00:00 2001 From: sergiuToporjinschi Date: Sun, 30 Jan 2022 22:34:01 +0200 Subject: [PATCH] Implement registration to M commands response --- octoprint_CalibrationTools/__init__.py | 1 - octoprint_CalibrationTools/api.py | 41 +++++++++---- octoprint_CalibrationTools/hooks.py | 60 +++++++++---------- .../static/js/CalibrationTools.js | 1 + .../templates/CalibrationTools_tab.jinja2 | 4 +- 5 files changed, 62 insertions(+), 45 deletions(-) diff --git a/octoprint_CalibrationTools/__init__.py b/octoprint_CalibrationTools/__init__.py index 6b00246..6fbaa0c 100644 --- a/octoprint_CalibrationTools/__init__.py +++ b/octoprint_CalibrationTools/__init__.py @@ -108,6 +108,5 @@ def __plugin_load__(): "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information, "octoprint.comm.protocol.firmware.info": __plugin_implementation__.firmwareInfo, "octoprint.comm.protocol.gcode.received": __plugin_implementation__.gCodeReceived, - "octoprint.comm.protocol.gcode.sending": __plugin_implementation__.gCodeSending, "octoprint.comm.protocol.temperatures.received": __plugin_implementation__.processTemp } diff --git a/octoprint_CalibrationTools/api.py b/octoprint_CalibrationTools/api.py index 41a926e..4e22888 100644 --- a/octoprint_CalibrationTools/api.py +++ b/octoprint_CalibrationTools/api.py @@ -1,20 +1,16 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals +from threading import Event import octoprint.plugin import flask - +import re CMD_TEST = "TEST" CMD_LOAD_STEPS = "loadSteps" CMD_START_EXTRUSION = "startExtrusion" CMD_SAVE_E_STEPS = "saveESteps" - -def someTestFunc(self, temps): - self._logger.debug("a ajuns %s", temps) - - class API(octoprint.plugin.SimpleApiPlugin): @staticmethod def get_api_commands(): @@ -43,8 +39,14 @@ class API(octoprint.plugin.SimpleApiPlugin): "msg": "Printer not ready, operation canceled" }) + # Register listener waiting response for M92 command + m92Event = Event() + self.registerGCodeWaiter("M92", self.m92GCodeResponse, m92Event) + + # Issue M92 command self._printer.commands("M92") + m92Event.wait() return flask.jsonify({ "data": self.data["steps"] }) @@ -69,14 +71,33 @@ class API(octoprint.plugin.SimpleApiPlugin): return if command == CMD_TEST: - # self.registerEventTemp("T0", 100, someTestFunc) - return flask.abort(503, { - "msg": "Printer not ready, operation canceled" - }) + self.registerGCodeWaiter("M92", self.someTestFunc) + return +############## HANDLERS ############## @staticmethod def startExtrusion(self, temps, *args): self._logger.debug("Temperature achieved, extrusion started %s, %s", temps, args) # Extrude self._printer.extrude(amount=120, speed=50) + + @staticmethod + def m92GCodeResponse(self, line, event): + reg = re.compile("echo:\s*(?P(?PM\d{1,3}) X(?P\d{1,3}.\d{1,3}) Y(?P\d{1,3}.\d{1,3}) Z(?P\d{1,3}.\d{1,3}) E(?P\d{1,3}.\d{1,3}))") + isM92command = reg.match(line) + if isM92command: + command = isM92command.group("command") + if isM92command.group("gCode") == "M92": + self.data["steps"]["X"] = float(isM92command.group("xVal")) + self.data["steps"]["Y"] = float(isM92command.group("yVal")) + self.data["steps"]["Z"] = float(isM92command.group("zVal")) + self.data["steps"]["E"] = float(isM92command.group("eVal")) + + # Send the new data to the UI to be reloaded + self._logger.debug("gCode: %s", command) + self._logger.debug("X: %s, Y:%s, Z:%s, E:%s", self.data["steps"]["X"], self.data["steps"]["Y"], self.data["steps"]["Z"], self.data["steps"]["E"]) + self._logger.debug("Finished data collection") + self.collectCommand = False + if event: + event.set() \ No newline at end of file diff --git a/octoprint_CalibrationTools/hooks.py b/octoprint_CalibrationTools/hooks.py index 2f5ab47..28e4917 100644 --- a/octoprint_CalibrationTools/hooks.py +++ b/octoprint_CalibrationTools/hooks.py @@ -6,46 +6,31 @@ import re import threading import traceback import types +import collections class Hooks(): trackTemp = True events = [] + gCodeWaiters = [] def gCodeReceived(self, comm, line, *args, **kwargs): - if not self.collectCommand: return line - self._logger.debug("collectCommand is true, collecting info") + if len(self.gCodeWaiters) <= 0 and not line.startswith('echo:'): + return line - reg = re.compile("echo:\s*(?P(?PM\d{1,3}) X(?P\d{1,3}.\d{1,3}) Y(?P\d{1,3}.\d{1,3}) Z(?P\d{1,3}.\d{1,3}) E(?P\d{1,3}.\d{1,3}))") - isM92command = reg.match(line) - if isM92command: - command = isM92command.group("command") - if isM92command.group("gCode") == "M92": - xValue = isM92command.group("xVal") - yValue = isM92command.group("yVal") - zValue = isM92command.group("zVal") - eValue = isM92command.group("eVal") - self.data["steps"]["X"] = float(xValue) - self.data["steps"]["Y"] = float(yValue) - self.data["steps"]["Z"] = float(zValue) - self.data["steps"]["E"] = float(eValue) - - # Send the new data to the UI to be reloaded - self._logger.debug(line) - self._logger.debug("gCode: %s", command) - self._logger.debug("X: %s", xValue) - self._logger.debug("Y: %s", yValue) - self._logger.debug("Z: %s", zValue) - self._logger.debug("E: %s", eValue) - self._logger.debug("Finished data collection") - self.collectCommand = False + reg = re.compile("echo:\s*(?PM\d{1,4})") + mCommand = reg.match(line) + if mCommand: + gCode = mCommand.group("gCode") + for waiter in self.gCodeWaiters: + if gCode.upper() == waiter["cmd"]: + arg = (line, *waiter["args"]) + if isinstance(waiter["func"], types.FunctionType): + arg = (self, *arg) + threading.Thread(target=waiter["func"], args=arg).start() + self.gCodeWaiters.remove(waiter) return line - def gCodeSending(self, comm, phase, cmd, cmd_type, gcode, subcode=None, tags=None, *args, **kwargs): - self._logger.debug("Sending GCODE [%s]", gcode) - if cmd == "M92": - self.collectCommand = True - def firmwareInfo(self, comm_instance, firmware_name, firmware_data, *args, **kwargs): self.data["info"] = { "firmware": firmware_data @@ -56,6 +41,7 @@ class Hooks(): def processTemp(self, comm_instance, parsed_temperatures, *args, **kwargs): if len(self.events) <= 0: return parsed_temperatures + try: self.checkAndTriggerEvent(parsed_temperatures.copy()) except Exception as e: @@ -71,14 +57,13 @@ class Hooks(): if event["tool"] == tool and curTemp >= event["targetTemp"]: arg = (temps, *event["args"]) if isinstance(event["func"], types.FunctionType): - self._logger.debug("addSelf") arg = (self, *arg) threading.Thread(target=event["func"], args=arg).start() self.events.remove(event) # Registering a temp event def registerEventTemp(self, tool, targetTemp, func, *arguments): - if func is None: + if func is None or not isinstance(func, collections.Callable): self._logger.warn("registerEventTemp: Attempt to register event without a function") return @@ -90,3 +75,14 @@ class Hooks(): } self._logger.debug("Registering event [%s, isFunction: %s]", event, isinstance(func, types.FunctionType)) self.events.append(event) + + # Registering a gCodeWaiter + def registerGCodeWaiter(self, command, func, *arguments): + if command is None or not re.compile("(?PM\d{1,4})").match(command.upper()) or func is None or not isinstance(func, collections.Callable): + self._logger.warn("registerGCodeAnswer: Attempt to register gCodeAnswer without a function or gCode command") + return + self.gCodeWaiters.append({ + "cmd": command.upper(), + "func": func, + "args": arguments + }) diff --git a/octoprint_CalibrationTools/static/js/CalibrationTools.js b/octoprint_CalibrationTools/static/js/CalibrationTools.js index 207ecaa..475eb5a 100644 --- a/octoprint_CalibrationTools/static/js/CalibrationTools.js +++ b/octoprint_CalibrationTools/static/js/CalibrationTools.js @@ -76,6 +76,7 @@ $(function () { self.tempRestart = function () { OctoPrint.system.executeCommand("core", "restart"); } + self.saveESteps = function () { OctoPrint.simpleApiCommand("CalibrationTools", "saveESteps", { "newESteps": self.results.newSteps() diff --git a/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 b/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 index 38c4373..b710ae0 100644 --- a/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 +++ b/octoprint_CalibrationTools/templates/CalibrationTools_tab.jinja2 @@ -7,10 +7,10 @@
- -