diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index 15bbf5eb..749eb0a9 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -127,6 +127,9 @@ Groups will be as follows: regex_firmware_splitter = re.compile("\s*([A-Z0-9_]+):") """Regex to use for splitting M115 responses.""" +regex_resend_linenumber = re.compile("(N|N:)?(?P%s)" % regex_int_pattern) +"""Regex to use for request line numbers in resend requests""" + def serialList(): baselist=[] if os.name=="nt": @@ -1862,13 +1865,7 @@ class MachineCom(object): def _handleResendRequest(self, line): try: - lineToResend = None - try: - lineToResend = int(line.replace("N:", " ").replace("N", " ").replace(":", " ").split()[-1]) - except: - if "rs" in line: - lineToResend = int(line.split()[1]) - + lineToResend = parse_resend_line(line) if lineToResend is None: return False @@ -3014,6 +3011,24 @@ def parse_firmware_line(line): result[key] = value return result +def parse_resend_line(line): + """ + Parses the provided resend line and returns requested line number. + + Args: + line (str): the line to parse + + Returns: + int or None: the extracted line number to resend, or None if no number could be extracted + """ + + match = regex_resend_linenumber.search(line) + if match is not None: + return int(match.group("n")) + + return None + + def gcode_command_for_cmd(cmd): """ Tries to parse the provided ``cmd`` and extract the GCODE command identifier from it (e.g. "G0" for "G0 X10.0"). diff --git a/tests/util/test_comm_helpers.py b/tests/util/test_comm_helpers.py index 762ac728..b3eb49b6 100644 --- a/tests/util/test_comm_helpers.py +++ b/tests/util/test_comm_helpers.py @@ -246,3 +246,18 @@ class TestCommHelpers(unittest.TestCase): from octoprint.util.comm import parse_firmware_line result = parse_firmware_line(line) self.assertDictEqual(expected, result) + + @data( + ("Resend:23", 23), + ("Resend: N23", 23), + ("Resend: N:23", 23), + ("rs 23", 23), + ("rs N23", 23), + ("rs N:23", 23), + ("rs N23 expected checksum 109", 23) # teacup, see #300 + ) + @unpack + def test_parse_resend_line(self, line, expected): + from octoprint.util.comm import parse_resend_line + result = parse_resend_line(line) + self.assertEqual(expected, result)