Scheduled commands and optimized bed mesh leveling

Hello again :slight_smile:

Using JSchuh’s macros for a while, I was wondering if this functionality would be worth including natively in Klipper. I am particularly referring to:

To achieve this, Klipper would need to know when layer changes occur (this information can come from the slicer or be found through pre-processing gcode and identifying layer changes in Klipper natively). Once Klipper “knows” when layer changes happen, it can execute scheduled commands. It would also “know” what coordinates correspond to the first layer, which makes it possible to determine the print-specific area to probe for optimized bed leveling.
To ensure that the pre-processing of layers at run-time does not slow Klipper down, the gcode reading and pre-processing would need to run in parallel to the execution of gcode commands during printing. I have been working on such a code (using Python’s multi-processing ability, passing gcode commands of entire layers for execution through a queue and error messages through a pipe) and I am currently stress testing it with real-world printing. Hence, implementing above mentioned features natively should be doable without too many issues and without running the risk of slowing Klipper down. This would make the functionality of JSchuh’s macros available to a wider user base, which may not be tech-savy enough to currently use it.
Just wondering what your opinion is.


  • Optimized mesh leveling is already being worked on for including into Klipper.
  • The other one (IMO) is a slicer function and there is no need to replicate it in the printer’s firmware

Hi Sineos

Great to read that optimized mesh leveling is already being worked on. Wasn’t aware of it. What is the approach being taken? Maybe you could point me towards the corresponding discussion.
Regarding scheduled gcode commands at layer change, I was referring to commands that can be added at runtime. Otherwise, it would indeed be a replication of a slicer function. Any thoughts?


I’m missing the point here. If I need such, then it depends on the model that I’m printing and as such, I’ll set it in the slicer. All modern slicers have such functions, so why should I add the complexity in the firmware?


Hi Sineos Thanks for the pointer! Re scheduled commands at layer change, JSchuh made a good argument:

“This is similar to what your slicer can already do, but I find it simpler, and you can schedule these commands while a print is active. As an example of usage, I added an LCD menu item to pause the print at the next layer change. This way the pause won’t mark the print by e.g. pausing inside an external perimeter.”

Another one would be that the user simply forgot to add e.g. a filament change pause when slicing and wants to correct the error while the print is already running. The use cases are certainly specialized as to when you would need such functionality. Nevertheless, having the option wouldn’t hurt.
Of course, macros can do this too. However, as you wrote yourself, beginner users copy those macros and then run into issues because the integration of the macros is sometimes not straight forward…


From experience, I can tell you that the Klipper project lead is very leery of adding “edge case” features that do not contribute a broad and measurable benefit for the average user base.
Main arguments are:

  • Added maintenance burden
  • Added documentation burden
  • Added configuration complexity

Without being the project lead, my feeling is that such a feature has below zero chance to get accepted.
Much higher impact features have been rejected for the above reasons and in this case I tend to happily agree, since it is an edge case where adequate alternatives exists.

Hi Sineos. Yes, in this particular case, the “cost-benefit” analysis is a tricky one to evaluate. I guess, if the corresponding code would be tidy and simple, it might be worth thinking about it. If not, I agree to not mind the hassle. Anyways, I am happy to see that optimized bed mesh will be native soon :slight_smile: Cheers, Florian