Part 7: The Printer Object
Many Klipper modules have what is called a get_status() wrapper these wrappers
are functions that report the state of the module. For instance, the toolhead
get_status wrapper reports things like position
, max_velocity
, and
max_accel
. The get_status wrapper is added to the printer
object
when Klipper starts up. By navigating the printer
object’s hierarchy, we can obtain
all manner of useful information that can be used in macros.
The tree structure is a mish-mash of types organized in various collections. These
collections frequently have more collections nested within them. It is quite complex.
I wrote a macro to help search for values within the printer tree
(Example: Search Printer Objects) since
I can never remember the exact names of anything.
You can see by the output of it, the printer
object carries booleans, floats,
strings, tuples, and even a list of lists.
printer.firmware_retraction.retract_length : 0.75
printer.firmware_retraction.unretract_extra_length : 0.0
printer.firmware_retraction.unretract_speed : 20.0
printer.firmware_retraction.retract_speed : 30.0
printer.probe
printer.probe.last_query : False
printer.bed_mesh
printer.bed_mesh.mesh_max : (275.0, 275.0)
printer.bed_mesh.profile_name : default
printer.bed_mesh.mesh_min : (25.0, 25.0)
printer.bed_mesh.probed_matrix :
[[-0.16875, -0.16375, -0.151875, -0.165625, -0.168125],
[-0.1125, 0.04125, -0.063125, -0.05, -0.13875],
[0.020625, -0.015, -0.009375, -0.04625, -0.013125],
[0.023125, 0.095625, 0.0475, 0.165625, -0.041875],
[0.070625, 0.06375, 0.043125, 0.01625, -0.03375]]
The printer
object is the cornerstone to writing useful macros because of the data
contained within it.
Say we don’t really want to have put that default pressure advance number in
there since it is already defined on the [extruder]
. We can reference that
value from within our macro like so.
[gcode_macro start_print]
gcode:
{% if not params.PA %}
{% set PA = printer.configfile.settings.extruder.pressure_advance %}
{% endif %}
M109 S{params.TOOL_TEMP} # Heat the tool to temperature and wait
{% if printer.homed_axes != 'XYZ' %}
G28 #Home All Axes
{% endif %}
SET_PRESSURE_ADVANCE ADVANCE={PA}
G92 E0 # Reset Extruder
G1 Z2.0 F3000 # Move Z Axis to travel height
G1 X0.1 Y20 Z0.2 F5000.0 # Move to start position
G1 X0.1 Y200.0 Z0.2 F1500.0 E15 # Draw the first line
G1 X0.4 Y200.0 Z0.2 F5000.0 # Move to side a little
G1 X0.4 Y20 Z0.3 F1500.0 E30 # Draw the second line
G92 E0 # Reset Extruder
G1 Z2.0 F3000 # Move Z Axis up to travel height
It should be noted, the configfile
tree contains both config
and
settings
branches. Both trees will have all the values that were read from
the config
file the last time klipper read it from the disk. The settings
tree
will have all of the currently configured values as typed values where the
config
tree will have them as strings
only.
It should also be noted that you cannot change any of the values found in the
printer
object. The only way to change anything is if there is an available gcode
to do so.
Our start print macro is going to start looking cluttered pretty quickly,
especially if we start doing comparisons and math on various values obtained
from the printer object. One thing we can do to help with this is to assign
the printer object or a specific section of it to a local variable that can
then be referenced instead. This can be done anywhere in the macro prior to
its first use, but to keep things concise, I personally prefer to put it at the top.
[gcode_macro start_print]
gcode:
{% set config = printer.configfile.settings %}
{% if not params.PA %}
{% set PA = config.extruder.pressure_advance %}
{% endif %}
This is especially helpful when macros begin to get more complex like when
comparing the position of the toolhead to the axis maximum
{% if printer.toolhead.position.z > ( printer.toolhead.axis_maximum.z - 40 ) %}
This could be made a bit tidier by assigning the position and axis limit
values to a variable and then evaluating them.
[gcode_macro end_print]
gcode:
{% set axismax = printer.toolhead.axis_maximum %}
{% set pos = printer.toolhead.position %}
#Move toolhead away from finished print
{% if pos.z <= ( axismax.z - 40 ) %}
G1 X10 Y10 Z{ pos.z + 40 }
{% else %}
G1 X10 Y10 Z{ axismax.z }
{% endif %}