Using rename_existing with GCODE Commands that have Parameters

I am trying to redefine the way M109 behaves for my dual extruder setup by defining a macro as apposed to running custom post processing scripts to remove M109 instances from generated GCODE files. This allows for all modifications to be contained in the Klipper config. I currently have a macro that polls for a temp threshold crossing, then immediately proceed with the print vs the default behavior of waiting for the temp to stabilize. Something like:

Calling the macro:

Macro impl:

variable_extruder: 0
#Logic: If active extruder is less than the target - 5 degrees, wait a second and check again; else proceed
#       This is to replace M109 commands in GCODE file as Klipper waits a long time to ensure stability
    {% if extruder|int == 0 %}
        {% for _ in range(1, 60) %}
            {% if printer.extruder.temperature < - 5 %}
                G4 P1000
            {% endif %}
        {% endfor %}
    {% endif %}
    {% if extruder|int == 1 %}
        {% for _ in range(1, 60) %}
            {% if printer.extruder1.temperature < - 5 %}
                G4 P1000
            {% endif %}
        {% endfor %}    
    {% endif %}

The above waits for up to 60 seconds for the temp to be reached within 5 degrees for a given extruder. I have read about the “rename_existing” feature but I am unsure how to use it with GCODE commands that have parameters, such as M109 that use the S param on the active extruder. Also, does the above implementation seem reasonable, or is there a better way to implement this functionality?


I’m not sure what you are actually trying to achieve:

  • M109 typically is issued in the slicer’s “print start” code and thus can be easily replaced with any other command
  • Klipper already offers the powerful temperature_wait command
  • You can easily bring this together in a customer PRINT_START macro that you call from your slicer’s print start section, passing the slicers internal variables. See klipper/sample-macros.cfg at 0407c24c78c65d590497020bf1003ac4f3ee5d0d · Klipper3d/klipper · GitHub for an example
  • Of course something similar can be done in the relevant “tool change gcode” or “color change gcode” of the slicers

Ah - temperature_wait! I was not familiar with this command. It seems to solve a big part of the question! Ok, so that is how I can do threshold crossing. The second part is to replace the behavior of M109 to also use temperature wait. The reason I am trying to do this is so I dont have to modify GCODE post process by removing M109 commands the slicer inserts after tool changes.

Here is my T0 macro (now with temperature_wait):

[gcode_macro T0]
    {% set min_target_temp = %}
    TEMPERATURE_WAIT SENSOR=extruder MINIMUM={min_target_temp}

Ex Gcode snippet:

G92 E0
T0         <---- Runs the above macro and waits until target temp - 5 is met
G92 E0
M104 T1 S200
M109 S215  <--- I dont want to run this and wait for temp stabilization!

Instead of post processing the slicer generated gcode to remove all M109 commands, how can I redefine M109 to use the temperature_wait command on the active extruder?

I’m still not sure why this post-processing / renaming is needed: Most (all?) slicers allow to setup custom Gcode for print start, print end, tool change etc. Why not just call your intended commands / macros there?

I included all the needed macros and commands for tool changing in the T0 macro, including the command that waits for the target temp of the extruder (using TEMPERATURE_WAIT). In the GCODE snippet block above, I show what the slicer (CURA 5.2.1) is inserting M109 in the GCODE because I am changing extruders. My slicer change tool setup is empty (as its all done in the T0 macro).

Because Cura inserts the M109 S215 command after my tool change as a standard, the result is that my T0 macro waits for the programmed temp then almost immediately hits the M109 S215 command and I needlessly wait for the settling behavior which I want to avoid as this is when my nozzles start to ooze. If the print continues immediately after the TEMPERATURE_WAIT command, the prints are much cleaner.

So, I tried post process removing the unwanted M109 commands, and that seemed to work great, but I didn’t want to maintain both slicer and Klipper configs for this to work as expected. Thus, I figured if I could make a behavioral modification to M109 in Klipper, it would allow me to keep generated GCODE with M109’s intact.

Not an expert for dual extrusion in Cura, but my understanding is that Cura only inserts what is defined in its machine settings:

out of these machine settings you should be able to call any Klipper command / macro and use the substitution variables that Cura offers: Settings and replacement patterns
E.g. you could do someting like SET_TEMPERATURE TEMP={material_print_temperature}, where

  • SET_TEMPERATURE is your own Klipper macro that processes the temperature provided by the TEMP= argument
  • {material_print_temperature} is the Cura variable that Cura will replace with the actual temperature of the defined material

Otherwise try:

[gcode_macro M109]
rename_existing: M109.1
    # Do whatever you want

To add to the above. When renaming standard gcode and need to stick to the standard gcode syntax like M190 S200, then you will have to use the rawparams variable and process it accordingly.

Something like:

[gcode_macro M190]
rename_existing: M190.1
  {% if rawparams %}
      {% set s_tmp = rawparams.split('S', 1)[1] %}
      { action_respond_info('s_tmp: ' ~ s_tmp) }
  {% endif %}