Klipper has no startup option for macros, but a delayed_gcode section with a short initial_duration runs any commands a moment after the printer is ready. The same section is Klipper's timer for anything that should happen later or on repeat.
To run a Klipper macro on startup, add a [delayed_gcode] section to printer.cfg with initial_duration set above zero and your macro’s name in its gcode: block. Klipper runs it that many seconds after the printer reaches the ready state, every time Klipper starts.
[delayed_gcode startup]
initial_duration: 1 # seconds after "ready"; 0 means never at startup
gcode:
MY_STARTUP_MACRO # any macro or command
How do you run a Klipper macro when the printer starts?
Add a [delayed_gcode] section with initial_duration set to a value above zero, and put the macro name in its gcode: option. Klipper starts the countdown when the printer enters the ready state and then runs the commands once. The default of 0 means the section never runs at startup.
Four details decide how it behaves:
- It runs on every start. A
RESTART, a FIRMWARE_RESTART or the restart after SAVE_CONFIG re-reads the config and reaches ready again, so the startup commands run each time.
- It needs a ready printer. If Klipper starts in an error state, such as a config error or an unreachable micro-controller (MCU), the section never runs.
- It takes no parameters. A
delayed_gcode gets the printer object but no params. To pass it a value, store the value in a macro variable with SET_GCODE_VARIABLE (see macro variables).
- It can call anything. The
gcode: block is a normal command template, so it can run your own macros, SET_LED, SET_PIN, M117 or Jinja2 logic.
Keep motion out of startup tasks: a G28 at boot moves the printer with nobody watching. For a pin that only needs to be on at power-up, such as a case light, the value: option of [output_pin] sets it during MCU configuration without any macro.
How to set up a Klipper startup macro
- Write the macro. Define what should happen at boot as a normal
[gcode_macro].
- Add the timer. Add a
[delayed_gcode] section with a unique name and initial_duration of 1 second or less.
- Call the macro. Put the macro name in the timer’s
gcode: block.
- Restart Klipper. Save printer.cfg and send
RESTART.
- Check the console. Confirm the macro’s output or effect once the printer reports ready.
[gcode_macro STARTUP]
gcode:
SET_LED LED=my_led RED=0 GREEN=0 BLUE=1 # "my_led": your LED section's name
M117 Ready
[delayed_gcode run_startup]
initial_duration: 1
gcode:
STARTUP
Load a bed mesh on startup
Add BED_MESH_PROFILE LOAD=default to a delayed_gcode. Klipper’s bed mesh module stopped loading the default profile at startup on 2023-02-01, and the Bed mesh documentation gives this section to bring the old behavior back:
[delayed_gcode bed_mesh_init]
initial_duration: .01
gcode:
BED_MESH_PROFILE LOAD=default
The profile has to exist in printer.cfg first. Every BED_MESH_CALIBRATE saves to default, and SAVE_CONFIG writes it to the file. If it is missing, the console shows bed_mesh: Unknown profile [default].
Skip this if your PRINT_START runs BED_MESH_CALIBRATE. Klipper’s documentation says loading default is then not required and “may produce unexpected results, especially with adaptive meshing.” Loading the profile at the start of each print, rather than at boot, is the documented alternative.
Klipper timer macros: run later, repeat, cancel
UPDATE_DELAYED_GCODE ID=<name> DURATION=<seconds> starts a delayed_gcode’s countdown from any macro or the console. Calling it again while the timer is pending restarts the countdown, and DURATION=0 cancels it. Always pass ID. Without it the command fails with missing ID.
A delayed_gcode set to initial_duration: 0 waits for that command. This one turns a light off 10 minutes after a print ends:
[delayed_gcode lights_off]
gcode:
SET_PIN PIN=caselight VALUE=0 # "caselight" is your [output_pin] name
[gcode_macro END_PRINT]
gcode:
TURN_OFF_HEATERS
M84
UPDATE_DELAYED_GCODE ID=lights_off DURATION=600
Add UPDATE_DELAYED_GCODE ID=lights_off DURATION=0 to your PRINT_START so a print started within those 10 minutes keeps its light.
To repeat, the section reschedules itself. This adapts the example from Klipper’s command templates page, which reads printer.extruder0. Current Klipper names the first extruder extruder.
[delayed_gcode report_temp]
initial_duration: 2
gcode:
UPDATE_DELAYED_GCODE ID=report_temp DURATION=2
{action_respond_info("Extruder temp: %.1f" % printer.extruder.temperature)}
Stop it with UPDATE_DELAYED_GCODE ID=report_temp DURATION=0. A repeating timer re-reads printer state on each run, so it can wait for a condition to change. A single macro only sees the state from when it was evaluated. For “do something after N minutes of no activity”, use [idle_timeout] instead. It defaults to 600 seconds and runs TURN_OFF_HEATERS and M84.
Why a delayed_gcode does not run
- No
initial_duration. Without it, or with 0, the section only runs when UPDATE_DELAYED_GCODE starts it.
- A command failed. Klipper reports the error in the console and skips the rest of that run. A repeating timer stops for good if a command before its
UPDATE_DELAYED_GCODE line fails, so put that line first, as above. A Jinja2 error stops it regardless, because the template is evaluated before anything runs.
- Wrong ID. A misspelled name returns “The value ‘…’ is not valid for ID” plus a suggestion or the list of valid names.
'params' is undefined. The section takes no parameters. Read values from printer or a macro variable instead.
- Klipper never reached ready. Fix the error shown at startup first.