From 8b005808848dd5395792dba8b9f470ac441c5e72 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Fri, 7 Jun 2019 19:30:17 -0400 Subject: [PATCH] gcode_macro: Parse variable_X parameters using ast.literal_eval() Signed-off-by: Kevin O'Connor --- config/example-extras.cfg | 10 +++++----- docs/Config_Changes.md | 5 +++++ docs/G-Codes.md | 3 ++- klippy/extras/gcode_macro.py | 20 ++++++++++++++++---- test/klippy/macros.cfg | 8 ++++---- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/config/example-extras.cfg b/config/example-extras.cfg index 1a7835a1..e418cd3a 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1454,11 +1454,11 @@ # 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. +# The given variable name will be assigned the given value (parsed +# as a Python literal) and will be available during macro expansion. +# For example, a config with "variable_fan_speed = 75" might have +# gcode commands containing "M106 S{ fan_speed * 255 }". Variables +# can be changed at run-time using the SET_GCODE_VARIABLE command. # Enable the "M118" and "RESPOND" extended commands. diff --git a/docs/Config_Changes.md b/docs/Config_Changes.md index dc6935fd..abce75be 100644 --- a/docs/Config_Changes.md +++ b/docs/Config_Changes.md @@ -6,6 +6,11 @@ All dates in this document are approximate. # Changes +20190607: The "variable_X" parameters of gcode_macro (along with the +VALUE parameter of SET_GCODE_VARIABLE) are now parsed as Python +literals. If a value needs to be assigned a string then wrap the value +in quotes so that it is evaluated as a string. + 20190606: The "samples", "samples_result", and "sample_retract_dist" config options have been moved to the "probe" config section. These options are no longer supported in the "delta_calibrate", "bed_tilt", diff --git a/docs/G-Codes.md b/docs/G-Codes.md index 03d35460..5d06a4a1 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -182,7 +182,8 @@ 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. + gcode_macro variable at run-time. The provided VALUE is parsed as a + Python literal. ## Custom Pin Commands diff --git a/klippy/extras/gcode_macro.py b/klippy/extras/gcode_macro.py index 977a763d..1918b0b9 100644 --- a/klippy/extras/gcode_macro.py +++ b/klippy/extras/gcode_macro.py @@ -3,7 +3,7 @@ # Copyright (C) 2018-2019 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. -import traceback, logging +import traceback, logging, ast import jinja2 @@ -100,9 +100,16 @@ class GCodeMacro: prefix = 'default_parameter_' self.kwparams = { o[len(prefix):].upper(): config.get(o) for o in config.get_prefix_options(prefix) } + self.variables = {} prefix = 'variable_' - self.variables = { o[len(prefix):]: config.get(o) - for o in config.get_prefix_options(prefix) } + for option in config.get_prefix_options(prefix): + try: + self.variables[option[len(prefix):]] = ast.literal_eval( + config.get(option)) + except ValueError as e: + raise config.error( + "Option '%s' in section '%s' is not a valid literal" % ( + option, config.get_name())) def get_status(self, eventtime): return dict(self.variables) cmd_SET_GCODE_VARIABLE_help = "Set the value of a G-Code macro variable" @@ -115,7 +122,12 @@ class GCodeMacro: return raise self.gcode.error("Unknown gcode_macro variable '%s'" % ( variable,)) - self.variables[variable] = value + try: + literal = ast.literal_eval(value) + except ValueError as e: + raise self.gcode.error("Unable to parse '%s' as a literal" % ( + value,)) + self.variables[variable] = literal cmd_desc = "G-Code macro" def cmd(self, params): if self.in_script: diff --git a/test/klippy/macros.cfg b/test/klippy/macros.cfg index 4886425f..8124aa3a 100644 --- a/test/klippy/macros.cfg +++ b/test/klippy/macros.cfg @@ -80,13 +80,13 @@ gcode: {% endif %} [gcode_macro TEST_variable] -variable_t: 12 +variable_t: 12.0 gcode: { printer.gcode.action_respond_info("TEST_variable") } - {% if t|float - 12.0 != printer.toolhead.position.y %} + {% if t - 12.0 != printer.toolhead.position.y %} M112 {% endif %} - {% if printer["gcode_macro TEST_variable"].t|float - 12.0 != 0.0 %} + {% if printer["gcode_macro TEST_variable"].t - 12.0 != 0.0 %} M112 {% endif %} SET_GCODE_VARIABLE MACRO=TEST_variable VARIABLE=t VALUE=17 @@ -95,7 +95,7 @@ gcode: [gcode_macro TEST_variable_part2] gcode: { printer.gcode.action_respond_info("TEST_variable_part2") } - {% if printer["gcode_macro TEST_variable"].t|float != 17.0 %} + {% if printer["gcode_macro TEST_variable"].t != 17.0 %} M112 {% endif %}