From 4ea6bcd1de4d5ec3ebb565c5f24db1dd3b8a2d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 27 Apr 2015 17:24:34 +0200 Subject: [PATCH] Smoothie compat fix: Only wait for ok's after GCODE commands Any unknown commands should just be piped through and not use up an acknowledgement. This new behaviour can be overridden via the new feature flag "unknownCommandsNeedAck", which will restore the former behaviour causing even unknown commands to use up an "ok". Also no line numbering or checksumming will happen. Shouldn't usually be of relevance for other firmwares, but in case of any compatibility issues introduced by this also added a new feature flag "sendChecksumWithNonGcode" that causes even unknown commands to be sent with a checksum if necessary. --- docs/configuration/config_yaml.rst | 10 +++++++++- src/octoprint/plugins/virtual_printer/virtual.py | 8 +++++--- src/octoprint/settings.py | 2 ++ src/octoprint/util/comm.py | 16 +++++++++++++--- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/docs/configuration/config_yaml.rst b/docs/configuration/config_yaml.rst index 11981684..c8640400 100644 --- a/docs/configuration/config_yaml.rst +++ b/docs/configuration/config_yaml.rst @@ -373,10 +373,18 @@ Use the following settings to enable or disable OctoPrint features: # during connect. waitForStartOnConnect: false - # Specifies whether OctoPrint should send linenumber + checksum with every command. Needed for + # Specifies whether OctoPrint should send linenumber + checksum with every printer command. Needed for # successful communication with Repetier firmware alwaysSendChecksum: false + # Specifies whether OctoPrint should also send linenumber + checksum with commands that are *not* + # detected as valid GCODE (as in, they do not match the regular expression "^\s*([GM]\d+|T)"). + sendChecksumWithUnknownCommands: false + + # Specifies whether OctoPrint should also use up acknowledgments ("ok") for commands that are *not* + # detected as valid GCODE (as in, they do not match the regular expression "^\s*([GM]\d+|T)"). + unknownCommandsNeedAck: false + # Whether to ignore the first ok after a resend response. Needed for successful communication with # Repetier firmware swallowOkAfterResend: false diff --git a/src/octoprint/plugins/virtual_printer/virtual.py b/src/octoprint/plugins/virtual_printer/virtual.py index 8f54cb28..a94afa93 100644 --- a/src/octoprint/plugins/virtual_printer/virtual.py +++ b/src/octoprint/plugins/virtual_printer/virtual.py @@ -149,6 +149,11 @@ class VirtualPrinter(): self._sendOk() continue + if data.strip() == "version": + from octoprint._version import get_versions + self.outgoing.put("OctoPrint VirtualPrinter v" + get_versions()["version"]) + continue + if len(data.strip()) > 0 and self._okBeforeCommandOutput: self._sendOk() @@ -394,7 +399,6 @@ class VirtualPrinter(): pass if tool >= settings().getInt(["devel", "virtualPrinter", "numExtruders"]): - self._sendOk() return try: @@ -406,7 +410,6 @@ class VirtualPrinter(): self._waitForHeatup("tool%d" % tool) if settings().getBoolean(["devel", "virtualPrinter", "repetierStyleTargetTemperature"]): self.outgoing.put("TargetExtr%d:%d" % (tool, self.targetTemp[tool])) - self._sendOk() def _parseBedCommand(self, line): try: @@ -418,7 +421,6 @@ class VirtualPrinter(): self._waitForHeatup("bed") if settings().getBoolean(["devel", "virtualPrinter", "repetierStyleTargetTemperature"]): self.outgoing.put("TargetBed:%d" % self.bedTargetTemp) - self._sendOk() def _performMove(self, line): matchX = re.search("X([0-9.]+)", line) diff --git a/src/octoprint/settings.py b/src/octoprint/settings.py index 8257cb6a..331b3e8f 100644 --- a/src/octoprint/settings.py +++ b/src/octoprint/settings.py @@ -132,6 +132,8 @@ default_settings = { "temperatureGraph": True, "waitForStartOnConnect": False, "alwaysSendChecksum": False, + "sendChecksumWithUnknownCommands": False, + "unknownCommandsNeedAck": False, "sdSupport": True, "sdAlwaysAvailable": False, "swallowOkAfterResend": True, diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index f1155bb1..13bbd783 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -155,6 +155,8 @@ class MachineCom(object): self._timeout = None self._alwaysSendChecksum = settings().getBoolean(["feature", "alwaysSendChecksum"]) + self._sendChecksumWithUnknownCommands = settings().getBoolean(["feature", "sendChecksumWithUnknownCommands"]) + self._unknownCommandsNeedAck = settings().getBoolean(["feature", "unknownCommandsNeedAck"]) self._currentLine = 1 self._resendDelta = None self._lastLines = deque([], 50) @@ -1498,6 +1500,9 @@ class MachineCom(object): # fetch command and optional linenumber from queue command, linenumber, _ = entry + # some firmwares (e.g. Smoothie) might support additional in-band communication that will not + # stick to the acknowledgement behaviour of GCODE, so we check here if we have a GCODE command + # at hand here and only clear our clear_to_send flag later if that's the case gcode_match = self._regex_command.search(command) is_gcode = gcode_match is not None @@ -1509,7 +1514,7 @@ class MachineCom(object): # line number predetermined, use that self._doSendWithChecksum(command, linenumber) else: - if self.isPrinting() or self._alwaysSendChecksum: + if (is_gcode or self._sendChecksumWithUnknownCommands) and (self.isPrinting() or self._alwaysSendChecksum): linenumber = self._currentLine self._addToLastLines(command) self._currentLine += 1 @@ -1517,12 +1522,17 @@ class MachineCom(object): else: self._doSendWithoutChecksum(command) + use_up_clear = not self._unknownCommandsNeedAck if is_gcode: - # trigger "sent" phase + # trigger "sent" phase and use up one "ok" self._process_command_phase("sent", command, gcode=gcode_match.group(1)) + use_up_clear = True + + # if we need to use up a clear, do that now + if use_up_clear: + self._clear_to_send.clear() # wait for the next clear - self._clear_to_send.clear() self._clear_to_send.wait() except: self._logger.exception("Caught an exception in the send loop")