Files
klipper-macros/CLAUDE.md
T
mangavalkandClaude Opus 5.5 b9d2f3a062 Nozzle guard in stop mode (brush log-only), wait for the nozzle before HOME
Test print start: guard peaks 1-8 in every phase except the brush scrub
(peak 47, 4 reads above 30 in a row), 0 I2C errors; a light finger push
gives 41. Stop mode for all phases, the brush stays log-only.

The contact homing in HOME restarted 6 times (sample spread too large)
while the nozzle was still heating to 150C; PRINT_WARMUP now waits for a
steady contact temperature first, as PRINT_START does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 23:25:28 +02:00

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.state first.

Repo layout

  • macros/klipper-macros.cfg is the only file printer.cfg includes; it includes everything else. It must be included after [include AFC/*.cfg] (a rename_existing of an AFC command only works if AFC loaded first). On the Pi, macros/ is linked as ~/printer_data/config/klipper-macros/ and scripts/ as ~/printer_data/config/klipper-macros-scripts/.
  • extras/*.py are linked into ~/klipper/klippy/extras/.
  • scripts/ MCU firmware update scripts (printer-specific IDs).
  • tools/effective_config.py expands 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 in klipper-macros.cfg matters for this.
  • RESUME and PAUSE are defined only in print/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_PRINT first purges with BLOBIFIER_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], in macros/save_variables.cfg.
  • PRINT_END and CANCEL_PRINT share _PRINT_CLEANUP (heaters including iHEATER_OFF, fan, M221 S100, bdwidth off). Anything that must happen at the end of every print goes there. RESTORE_GCODE_STATE restores the flow (M221), so reset flow after it, not before.
  • Do not use G10/G11 in macros: Klipper's G10 retracts only once until a G11, and nothing on this printer sends G11. Use _NOZZLE_RETRACT (remembered in the saved variable nozzle_retract); PRINT_START undoes 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 an M117 line: M117 shows the raw rest of the line, comment included.
  • Errors and warnings go through _ERROR / _WARN (macros/messages.cfg), not action_raise_error / RESPOND TYPE=error, so they also show on the display. action_raise_error aborts while rendering, so an M117 in the same macro would never run. No double quotes in MSG/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: in mode: stop that is an instant shutdown.
  • After a refactor run python tools/effective_config.py HEAD and check that only the intended sections changed.
  • Render-test macros with Jinja2 using Klipper's delimiters (jinja2.Environment('{%', '%}', '{', '}')) and mocked printer objects.

Rules for the Python modules (extras/)

  • Klipper only loads changed .py files when the Klipper service restarts (sudo systemctl restart klipper); RESTART and FIRMWARE_RESTART keep the old code in memory.
  • Event handlers must never raise: an exception in a handler shuts Klipper down. Example: Beacon sends homing:home_rails_end with rails=[] and a homing state whose get_trigger_position raises.
  • 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-181; 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.