diff --git a/config/example-extras.cfg b/config/example-extras.cfg index b4ec6750..d3e1f1c7 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1487,6 +1487,13 @@ # command "MY_DELAY" would evaluate to "G4 P50". The default is to # require that all parameters used in the gcode script be present in # the command invoking the macro. +#variable_: +# One may specify any number of options with a "variable_" prefix. +# The given variable name will then be available during macro +# expansion. For example, a config with "variable_my_name = zebra" +# might have a gcode config containing "M117 My name is {my_name}". +# Variables can be changed at run-time using the SET_GCODE_VARIABLE +# command. # Enable the "M118" and "RESPOND" extended commands. diff --git a/docs/G-Codes.md b/docs/G-Codes.md index 3c885677..966371e7 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -176,6 +176,14 @@ The following standard commands are supported: - `STATUS`: Report the Klipper host software status. - `HELP`: Report the list of available extended G-Code commands. +## G-Code Macro Commands + +The following command is available when a "gcode_macro" config section +is enabled: +- `SET_GCODE_VARIABLE MACRO= VARIABLE= + VALUE=`: This command allows one to change the value of a + gcode_macro variable at run-time. + ## Custom Pin Commands The following command is available when an "output_pin" config section diff --git a/klippy/extras/gcode_macro.py b/klippy/extras/gcode_macro.py index 57b2153d..a29e1248 100644 --- a/klippy/extras/gcode_macro.py +++ b/klippy/extras/gcode_macro.py @@ -77,17 +77,37 @@ def load_config(config): class GCodeMacro: def __init__(self, config): - self.alias = config.get_name().split()[1].upper() + name = config.get_name().split()[1] + self.alias = name.upper() printer = config.get_printer() config.get('gcode') gcode_macro = printer.try_load_module(config, 'gcode_macro') self.template = gcode_macro.load_template(config, 'gcode') self.gcode = printer.lookup_object('gcode') self.gcode.register_command(self.alias, self.cmd, desc=self.cmd_desc) + self.gcode.register_mux_command("SET_GCODE_VARIABLE", "MACRO", + name, self.cmd_SET_GCODE_VARIABLE, + desc=self.cmd_SET_GCODE_VARIABLE_help) self.in_script = False prefix = 'default_parameter_' self.kwparams = { o[len(prefix):].upper(): config.get(o) for o in config.get_prefix_options(prefix) } + prefix = 'variable_' + self.variables = { o[len(prefix):]: config.get(o) + for o in config.get_prefix_options(prefix) } + def get_status(self, eventtime): + return dict(self.variables) + cmd_SET_GCODE_VARIABLE_help = "Set the value of a G-Code macro variable" + def cmd_SET_GCODE_VARIABLE(self, params): + variable = self.gcode.get_str('VARIABLE', params) + value = self.gcode.get_str('VALUE', params) + if variable not in self.variables: + if variable in self.kwparams: + self.kwparams[variable] = value + return + raise self.gcode.error("Unknown gcode_macro variable '%s'" % ( + variable,)) + self.variables[variable] = value cmd_desc = "G-Code macro" def cmd(self, params): if self.in_script: @@ -95,6 +115,7 @@ class GCodeMacro: "Macro %s called recursively" % (self.alias,)) kwparams = dict(self.kwparams) kwparams.update(params) + kwparams.update(self.variables) kwparams['printer'] = self.template.create_status_wrapper() kwparams['params'] = params self.in_script = True