gcode: Fix detection of some "extended" g-code commands

Fix typo that resulted in _get_extended_params() being called for all
commands.  Allow "extended" g-code commands to contain numbers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2020-01-07 19:06:55 -05:00
parent ac863a95b6
commit 005cfea5c3
3 changed files with 20 additions and 17 deletions

View File

@ -389,9 +389,7 @@
###################################################################### ######################################################################
# G-Code macros (one may define any number of sections with a # G-Code macros (one may define any number of sections with a
# "gcode_macro" prefix). If G-Code macro names contain any numbers # "gcode_macro" prefix).
# they must all be at the end of the macro's name.
# (example: test_macro25 is acceptable, but macro25_test3 is not).
#[gcode_macro my_cmd] #[gcode_macro my_cmd]
#gcode: #gcode:
# A list of G-Code commands to execute in place of "my_cmd". See # A list of G-Code commands to execute in place of "my_cmd". See
@ -411,13 +409,11 @@
# One may specify any number of options with a "variable_" prefix. # One may specify any number of options with a "variable_" prefix.
# The given variable name will be assigned the given value (parsed # The given variable name will be assigned the given value (parsed
# as a Python literal) and will be available during macro expansion. # as a Python literal) and will be available during macro expansion.
# For example, a macro called set_fan with # For example, a config with "variable_fan_speed = 75" might have
# "variable_fan_speed = 75" might have gcode commands containing # gcode commands containing "M106 S{ fan_speed * 255 }". Variables
# "M106 S{ fan_speed * 255 }". Variables can be changed at run-time # can be changed at run-time using the SET_GCODE_VARIABLE command
# using the SET_GCODE_VARIABLE command from within any G-Code Macro. # (see docs/Command_Templates.md for details). Variable names may
# Example, from a macro called my_macro2 I could state: # not use upper case characters.
# "SET_GCODE_VARIABLE MACRO=set_fan VARIABLE=fan_speed VALUE=50"
# Variable names may not use upper case characters.
# Execute a gcode on a set delay. # Execute a gcode on a set delay.
#[delayed_gcode my_delayed_gcode] #[delayed_gcode my_delayed_gcode]

View File

@ -2,10 +2,10 @@ This document provides information on implementing G-Code command
sequences in gcode_macro (and similar) config sections. sequences in gcode_macro (and similar) config sections.
### G-Code Macro Naming ### G-Code Macro Naming
Case is not important when creating a G-Code macro name. MY_MACRO and
Case is not important for the G-Code macro name - MY_MACRO and
my_macro will evaluate the same and may be called in either upper or my_macro will evaluate the same and may be called in either upper or
lower case. If any numerical digits are used in the macro name they lower case.
must all be placed at the end of the name.
### Formatting of G-Code in the config ### Formatting of G-Code in the config

View File

@ -61,6 +61,14 @@ class GCodeParser:
self.toolhead = None self.toolhead = None
self.heaters = None self.heaters = None
self.axis2pos = {'X': 0, 'Y': 1, 'Z': 2, 'E': 3} self.axis2pos = {'X': 0, 'Y': 1, 'Z': 2, 'E': 3}
def is_traditional_gcode(self, cmd):
# A "traditional" g-code command is a letter and followed by a number
try:
cmd = cmd.upper().split()[0]
val = float(cmd[1:])
return cmd[0].isupper() and cmd[1].isdigit()
except:
return False
def register_command(self, cmd, func, when_not_ready=False, desc=None): def register_command(self, cmd, func, when_not_ready=False, desc=None):
if func is None: if func is None:
if cmd in self.ready_gcode_handlers: if cmd in self.ready_gcode_handlers:
@ -71,7 +79,7 @@ class GCodeParser:
if cmd in self.ready_gcode_handlers: if cmd in self.ready_gcode_handlers:
raise self.printer.config_error( raise self.printer.config_error(
"gcode command %s already registered" % (cmd,)) "gcode command %s already registered" % (cmd,))
if not (len(cmd) >= 2 and not cmd[0].isupper() and cmd[1].isdigit()): if not self.is_traditional_gcode(cmd):
origfunc = func origfunc = func
func = lambda params: origfunc(self._get_extended_params(params)) func = lambda params: origfunc(self._get_extended_params(params))
self.ready_gcode_handlers[cmd] = func self.ready_gcode_handlers[cmd] = func
@ -363,14 +371,13 @@ class GCodeParser:
maxval=maxval, above=above, below=below) maxval=maxval, above=above, below=below)
extended_r = re.compile( extended_r = re.compile(
r'^\s*(?:N[0-9]+\s*)?' r'^\s*(?:N[0-9]+\s*)?'
r'(?P<cmd>[a-zA-Z_][a-zA-Z_]+)(?:\s+|$)' r'(?P<cmd>[a-zA-Z_][a-zA-Z0-9_]+)(?:\s+|$)'
r'(?P<args>[^#*;]*?)' r'(?P<args>[^#*;]*?)'
r'\s*(?:[#*;].*)?$') r'\s*(?:[#*;].*)?$')
def _get_extended_params(self, params): def _get_extended_params(self, params):
m = self.extended_r.match(params['#original']) m = self.extended_r.match(params['#original'])
if m is None: if m is None:
# Not an "extended" command raise self.error("Malformed command '%s'" % (params['#original'],))
return params
eargs = m.group('args') eargs = m.group('args')
try: try:
eparams = [earg.split('=', 1) for earg in shlex.split(eargs)] eparams = [earg.split('=', 1) for earg in shlex.split(eargs)]