something to add to the tutorial:
The SET_GCODE_VARIABLE
and SAVE_VARIABLE
commands in klipper require that you pass them Python literals. Simple strings and numbers are pretty easy but what about complex types like arrays or objects? This has been a stumbling block for more ambitious macros. If you have tried the tojson
filter you have probably not had a lot of luck. Here is a way to do it using the pprint
filter:
[gcode_macro TEST_STUFF]
variable_hello: None
gcode:
{action_respond_info(printer['gcode_macro TEST_STUFF'].hello | pprint)}
{% set my_array = [1, 2.0, "heater_bed", None, 3] %}
{% set my_object = {"name": "Hello World it's \"Fred\" calling", "some_data": my_array} %}
{action_respond_info("my_array: %s" % (my_array | pprint | replace("\n", "") | replace("\"", "\\\"")))}
{action_respond_info("my_object: %s" % (my_object | pprint | replace("\n", "") | replace("\"", "\\\"")))}
SET_GCODE_VARIABLE MACRO=TEST_STUFF VARIABLE=hello VALUE="{my_object | pprint | replace("\n", "") | replace("\"", "\\\"")}"
Output of 2 calls:
$ TEST_STUFF
// None
// my_array: [1, 2.0, 'heater_bed', None, 3]
// my_object: {'name': 'Hello World it\'s \"Fred\" calling', 'some_data': [1, 2.0, 'heater_bed', None, 3]}
$ TEST_STUFF
// {'name': 'Hello World it\'s "Fred" calling',
// 'some_data': [1, 2.0, 'heater_bed', None, 3]}
// my_array: [1, 2.0, 'heater_bed', None, 3]
// my_object: {'name': 'Hello World it\'s \"Fred\" calling', 'some_data': [1, 2.0, 'heater_bed', None, 3]}
-
pprint
converts Python objects to their Python Literal format but it adds newlines when the object is too large to comfortably read. -
replace("\n", "")
deletes the newlines -
replace("\"", "\\\"")
escapes double quotes in the string so it can be passed to a klipper command wrapped in double quotes.
The end result is a valid Python literal that you can pass to the macros:
SET_GCODE_VARIABLE MACRO=TEST_STUFF VARIABLE=hello VALUE="{my_object | pprint | replace("\n", "") | replace("\"", "\\\"")}"
SAVE_VARIABLE VARIABLE="my_saved_variable" VALUE="{my_object | pprint | replace("\n", "") | replace("\"", "\\\"")}"