6.0 KiB
klipper-macros
Klipper macros, Klipper modules and scripts for one printer, installed on
the printer's Raspberry Pi with install.sh and updated through Moonraker.
See README.md for the user-facing description.
The printer
Voron 2.4 350, Klipper + Moonraker + Mainsail on a Raspberry Pi 4
(http://mainsailos.local, Moonraker API on port 80). AFC Box Turtle with
5 lanes, Blobifier purge bucket, Beacon (Z homing and probing), Nitehawk-SB
toolboard (USB), Leviathan mainboard as USB-CAN bridge, bd_pressure
(load-check firmware, branch load-check-extension in
D:\Claude\bd_pressure-load-check\bd_pressure), bdwidth (CCD width/motion sensor on USB; switched off: its motion reading
stays at 0, its width compensation made the flow jump 77-119% and a USB
dropout once shut down Klipper. The macros work with or without
[bdwidth fila_width_0]; clogs and breaks are caught by AFC's buffer fault
detection, filament_error_sensitivity), iHeater chamber heater.
Working with the printer
- Read freely through Moonraker:
GET /server/files/config/<path>,/server/files/logs/klippy.log,/printer/objects/query?...,/server/gcode_store. The merged config Klipper loaded is in klippy.log after===== Config file =====. - Do not change anything on the printer (upload files, edit config, send G-code, restart services) unless the user asks for that specific action. Prepare files here and let the user upload them.
- Never run anything that moves the printer or heats while a print may be
running; check
print_stats.statefirst.
Repo layout
macros/klipper-macros.cfgis the only fileprinter.cfgincludes; it includes everything else. It must be included after[include AFC/*.cfg](arename_existingof an AFC command only works if AFC loaded first). On the Pi,macros/is linked as~/printer_data/config/klipper-macros/andscripts/as~/printer_data/config/klipper-macros-scripts/.extras/*.pyare linked into~/klipper/klippy/extras/.scripts/MCU firmware update scripts (printer-specific IDs).tools/effective_config.pyexpands the includes like Klipper and compares the result between git refs.
Rules for macro changes
- Never define the same
[gcode_macro X]in two files. Klipper merges sections with the same name and the later file wins completely (this is how heat_soak.cfg's RESUME silently replaced the real RESUME). Include order inklipper-macros.cfgmatters for this. RESUMEandPAUSEare defined only inprint/pause_resume.cfg. AFC renames PAUSE/RESUME at startup and wraps them:PAUSE -> AFC_PAUSE -> PAUSE -> PAUSE_BASE,RESUME -> AFC_RESUME -> RESUME -> HEAT_SOAK_RESUME -> _RESUME_PRINT -> RESUME_BASE. After a PAUSE,_RESUME_PRINTfirst purges withBLOBIFIER_CHECKED(_RESUME_PURGE); a failed check raises an error, which aborts the whole chain (AFC_RESUME's restore too), so the printer stays paused.- Only one
[save_variables], inmacros/save_variables.cfg. PRINT_ENDandCANCEL_PRINTshare_PRINT_CLEANUP(heaters includingiHEATER_OFF, fan,M221 S100, bdwidth off). Anything that must happen at the end of every print goes there.RESTORE_GCODE_STATErestores the flow (M221), so reset flow after it, not before.- Do not use
G10/G11in macros: Klipper'sG10retracts only once until aG11, and nothing on this printer sendsG11. Use_NOZZLE_RETRACT(remembered in the saved variablenozzle_retract);PRINT_STARTundoes it over the bucket with_NOZZLE_UNRETRACT. - Inside
gcode:use;for comments on G-code lines;#lines are stripped by the config parser. Never put a comment on anM117line: M117 shows the raw rest of the line, comment included. - Errors and warnings go through
_ERROR/_WARN(macros/messages.cfg), notaction_raise_error/RESPOND TYPE=error, so they also show on the display.action_raise_erroraborts while rendering, so anM117in the same macro would never run. No double quotes inMSG/DISPLAY. - Nozzle guard (
print/nozzle_guard.cfg,extras/bdp_guard.py): wrap only moves where nothing may touch the nozzle in_GUARD_ON PHASE=x/_GUARD_OFF. Never leave it on across contact homing, extrusion, purges, the Blobifier park or AFC cuts and loads: inmode: stopthat is an instant shutdown. - After a refactor run
python tools/effective_config.py HEADand check that only the intended sections changed. - Render-test macros with Jinja2 using Klipper's delimiters
(
jinja2.Environment('{%', '%}', '{', '}')) and mockedprinterobjects.
Rules for the Python modules (extras/)
- Klipper only loads changed
.pyfiles when the Klipper service restarts (sudo systemctl restart klipper);RESTARTandFIRMWARE_RESTARTkeep the old code in memory. - Event handlers must never raise: an exception in a handler shuts Klipper
down. Example: Beacon sends
homing:home_rails_endwithrails=[]and a homing state whoseget_trigger_positionraises. - Keep them read-only wrappers where possible (look up the other module's object, do not patch third-party files).
Reference values
- Purge check (150 mm Blobifier purge): good load = longest pressure 13-18 s, peak 64-246 (ASA at 250-260C peaks highest); empty nozzle about 30 ms. A real failed load in a print start (AFC reported the lane loaded, nothing reached the nozzle): longest 1915 ms, peak 45, caught by the 5000 ms limit.
- Nozzle guard (bdp_guard): peaks 1-8 in home_xy, QGL, Z homing, mesh and the Z check; the brush scrub 47 (4 reads above 30 in a row, so it runs in log mode); a light finger push on the cold nozzle gives 41 (threshold 30).
- Z check after a contact homing: Beacon vs Klipper Z about 0.06 mm.
- XY drift check: endstop noise about 0.01-0.02 mm; limit 0.1 mm (one motor skipping one cycle = 0.4 mm shows as 0.2 mm in X and Y).
Git
- LF line endings everywhere (
.gitattributes); the files run on Linux. - Commit only when the user says so; never push without asking. Remote:
https://mangavalk.com/mangavalk/klipper-macros.git.