# klipper-macros My Klipper macros, the small Klipper modules they need, and helper scripts, from a Voron 2.4 (350) with an AFC Box Turtle (5 lanes), Blobifier, Beacon, Nitehawk-SB toolboard, bd_pressure, bdwidth and an iHeater chamber heater. Installs with one script and updates through Moonraker's update manager. ## Contents ### Macros (`macros/`) `printer.cfg` includes only `macros/klipper-macros.cfg`; that file includes everything below, grouped by topic. Comment out what you do not use there. | File | Macros | Needs | |---|---|---| | `save_variables.cfg` | the one `[save_variables]` for all macros (file `bd_pa_variables.cfg` in the config folder) | — | | **blobifier/** | | | | `blobifier.cfg` | `BLOBIFIER`, `BLOBIFIER_CLEAN`, `BLOBIFIER_PARK`, `BLOBIFIER_SHAKE_BUCKET`, ...: purge bucket and nozzle brush for AFC (Turtleblobifier, heavily modified) | Blobifier hardware, AFC | | `blobifier_hw.cfg` | servo and bucket switch pins | — | | **print/** | | | | `print_start_end.cfg` | `PRINT_WARMUP`, `PRINT_START`, `PRINT_END` | Beacon, AFC, Blobifier, `HEAT_SOAK`, iHeater, bdwidth, bd_pressure PA macros | | `pause_resume.cfg` | `PAUSE`, `RESUME`, `CANCEL_PRINT`, `M600` (RESUME also handles a running `HEAT_SOAK`, and after a PAUSE purges 40 mm with `BLOBIFIER_CHECKED` first: a failed check keeps the print paused, `RESUME PURGE=0` skips the purge; CANCEL_PRINT runs the same cleanup as `PRINT_END`) | `heating/heat_soak.cfg`, `leds/`, `blobifier/`, `afc/purge_check.cfg` | | `filament.cfg` | `LOAD_FILAMENT`, `UNLOAD_FILAMENT` | — | | `homing.cfg` | `HOME` | — | | `idle_timeout.cfg` | `[idle_timeout]`: heaters, chamber heater and motors off | iHeater macros | | **heating/** | | | | `heat_soak.cfg` | `HEAT_SOAK`, `STOP_HEAT_SOAK`, `CANCEL_HEAT_SOAK`, `HEAT_SOAK_RESUME`, `RESUME` | — | | `soak_my_bed.cfg` | `SOAK_MY_BED` (homes and levels first) | soak-my-bed | | `bed_fans.cfg` | Bed fans through `SET_HEATER_TEMPERATURE`/`M190`/`M140`/`TURN_OFF_HEATERS` overrides | `[fan_generic BedFans]` | | `chamber_iheater.cfg` | iHeater MCU, heater and sensors, `M141`, `M191`, `iHEATER_ON`, `iHEATER_OFF` | iHeater chamber heater | | `filament_drying.cfg` | `START_DRYING`, `STOP_DRYING`, `STATUS_DRYING` | bed fans, chamber heater (optional) | | **afc/** | | | | `xy_safety_check.cfg` | `AFC_XY_SAFETY_CHECK`, `_AFC_STORE_HOME_REFERENCE`, `AFC_XY_RESUME`: lost-step check around tool changes | `extras/xy_drift.py` (CoreXY) | | `lane_tools.cfg` | `LANE_FEED_UNTIL_HUB_OPEN`, `LANE_FEED_ABORT` | AFC | | `purge_check.cfg` | `BLOBIFIER_CHECKED`: checks every AFC purge with bd_pressure (and optionally bdwidth motion) | Blobifier, AFC, `extras/bdpressure_check.py` + bd_pressure load-check firmware, `extras/bdwidth_status.py` | | `purge_until_empty.cfg` | `PURGE_UNTIL_EMPTY`: purges a snapped filament out until there is no more nozzle pressure | same as `purge_check.cfg` | | **pressure_advance/** | | | | `bd_pa_spoolman.cfg` + `bd_pa_*.sh` | `LANE_CALIBRATE_PA`, `PA_CALIBRATE_ALL_LANES`, `LANE_RECAL_PA`, `SET_SPOOL_ID`, `PA_STATUS`: pressure advance per lane/spool, cached locally and in Spoolman | bd_pressure, AFC, Spoolman, `gcode_shell_command` | | **spoolman/** | | | | `active_spool.cfg` | `SET_ACTIVE_SPOOL`, `CLEAR_ACTIVE_SPOOL` | Spoolman in Moonraker | | **leds/** | | | | `stealthburner_leds.cfg` | Stealthburner LED effects and `_status_*` macros | `led_effect` | | **sensors/** | | | | `motion_sensor.cfg` | PIR motion sensor switching the case light | sensor on a pin, `[output_pin caselight]` | ### Klipper modules (`extras/`) | File | For | |---|---| | `xy_drift.py` | `AFC_XY_SAFETY_CHECK`: measures lost XY steps from the stepper step counts at the endstop triggers (CoreXY). The toolhead position after homing cannot show lost steps. | | `bdwidth_status.py` | exposes bdwidth's motion counter and width to macros | | `bdpressure_check.py` | bd_pressure load check (`BDP_CHECK_START/STOP/QUERY`). Needs the load-check firmware from the bd_pressure `load-check-extension` branch; on stock firmware it reports "not available" and does nothing. | ### Scripts (`scripts/`) Firmware update scripts for all MCUs (Klipper and Katapult). They contain this printer's CAN UUIDs and serial IDs: see [scripts/README.md](scripts/README.md) before using them on another printer. ### Tools (`tools/`) `effective_config.py` builds the config Klipper gets from `klipper-macros.cfg` (includes expanded, duplicate sections merged) and compares it between git refs, for example `python tools/effective_config.py HEAD` after a change. `CLAUDE.md` has the notes for working on this repo with Claude Code. ## Install On the Klipper host: ```bash cd ~ && git clone https://mangavalk.com/mangavalk/klipper-macros.git ~/klipper-macros/install.sh ``` `install.sh`: - links `extras/*.py` into `~/klipper/klippy/extras/` (and hides them from Klipper's update manager), - links `macros/` to `~/printer_data/config/klipper-macros` and `scripts/` to `~/printer_data/config/klipper-macros-scripts`, so the files show up in Mainsail/Fluidd and can be edited there, - makes the shell scripts executable, - adds this section to `moonraker.conf` (once, with a backup): ```ini [update_manager klipper-macros] type: git_repo path: ~/klipper-macros origin: https://mangavalk.com/mangavalk/klipper-macros.git primary_branch: main managed_services: klipper install_script: install.sh ``` Then: 1. In `printer.cfg`, after `[include mainsail.cfg]` **and after the AFC includes** (`[include AFC/*.cfg]`): ```ini [include klipper-macros/klipper-macros.cfg] ``` `bd_pa_spoolman.cfg` wraps AFC's `SET_SPOOL_ID` with `rename_existing`, which only works when AFC is loaded first; otherwise Klipper stops with `Existing command 'SET_SPOOL_ID' not found in gcode_macro rename`. 2. Restart the **Klipper service** (`sudo systemctl restart klipper`, or Mainsail → services → klipper → restart). A `RESTART` or `FIRMWARE_RESTART` does not load new or changed Python modules. 3. Restart Moonraker once, so the update manager shows `klipper-macros`. Updates then come through Moonraker; it re-runs `install.sh` and restarts Klipper. ### Switching from copies in the config folder If these macros already exist as files in your config folder (as on the original printer: `Macros/*.cfg` and `bd_pa_afc_spoolman.cfg`), remove those includes when adding `klipper-macros.cfg`, otherwise the macros are defined twice and the old copy may win: - remove `[include bd_pa_afc_spoolman.cfg]` and `[include ./blobifier/blobifier.cfg]` from `printer.cfg`, - remove `[include ./Macros/macros.cfg]` and add `[include klipper-macros/klipper-macros.cfg]` after `[include AFC/*.cfg]`, - keep including what is not in this repo yourself, for example `[include Macros/timelapse.cfg]` and `[include Macros/TEST_SPEED.cfg]`. `bd_pa_variables.cfg` (saved PA values and the Blobifier blob count) stays where it is, in the config folder; it is data, not part of the repo. Before, both `blobifier.cfg` and `bd_pa_afc_spoolman.cfg` had their own `[save_variables]`; Klipper merged them and the last one won, so the blob count was already stored in `bd_pa_variables.cfg` and `blobifier/blob_vars.cfg` was no longer used. Now it is defined once, in `save_variables.cfg`. ## Adapting to another printer These are the settings of one printer. Before using a file, check: - **Names:** `fila_width_0` (bdwidth), `bd_pa` (bd_pressure), `sb_leds`, `caselight`, `BedFans`, `iHeater_H`, lane names `lane1..lane5`. - **Pins and serial IDs:** `blobifier/blobifier_hw.cfg` (`PC1`, `PC3`), `sensors/motion_sensor.cfg` (`PC0`), `heating/chamber_iheater.cfg` (serial ID). - **Positions:** the bed centre `X175 Y175` (350 mm bed) in `print/homing.cfg` and `print/print_start_end.cfg`. `AFC_XY_SAFETY_CHECK` uses the axis limits from your config. - **Settings at the top of a file** (`variable_...`): `afc/purge_check.cfg` (`mode: "enforce"`, `motion_check: False` because this printer's bdwidth motion reading is unreliable), `pressure_advance/bd_pa_spoolman.cfg` (`spoolman_url`), `heating/bed_fans.cfg`, `heating/filament_drying.cfg`. - `xy_drift.py` is for CoreXY only. Comment out files you do not need in `klipper-macros.cfg`. ## Uninstall ```bash ~/klipper-macros/install.sh --uninstall ``` Then remove the include from `printer.cfg` and the `[update_manager klipper-macros]` section from `moonraker.conf`, and restart the Klipper service. ## Credits Some files started from other projects and were modified here; their original licenses apply to those parts: | File | Based on | |---|---| | `blobifier/` | [Turtleblobifier](https://github.com/ImSundee/Turtleblobifier) (AFC version of [Dendrowen/Blobifier](https://github.com/Dendrowen/Blobifier)) | | `leds/stealthburner_leds.cfg` | [tanaes/whopping_Voron_mods](https://github.com/tanaes/whopping_Voron_mods) (Rainbow Barf logo LEDs) | | `heating/bed_fans.cfg` | Ellis' bed fan macros ([ellis3dp.com](https://ellis3dp.com/Print-Tuning-Guide/)) | | `heating/heat_soak.cfg` | community `HEAT_SOAK` macro | | `heating/chamber_iheater.cfg` | iHeater vendor configuration | | `heating/filament_drying.cfg` | community filament drying macro | | `print/pause_resume.cfg`, `print/filament.cfg` | [KlipperScreen recommended macros](https://klipperscreen.readthedocs.io/en/latest/macros/#recommended) | | `scripts/` | [Voron docs: automating MCU updates](https://docs.vorondesign.com/community/howto/drachenkatze/automating_klipper_mcu_updates.html), [Esoterical's CANBus guide](https://canbus.esoterical.online/) | Uses: [Klipper](https://github.com/Klipper3d/klipper), [AFC-Klipper-Add-On](https://github.com/ArmoredTurtle/AFC-Klipper-Add-On), [bd_pressure](https://github.com/markniu/bd_pressure), [bdwidth](https://github.com/markniu/bdwidth), [klipper-led_effect](https://github.com/julianschill/klipper-led_effect), [soak-my-bed](https://github.com/marcofailli/soak-my-bed), [Spoolman](https://github.com/Donkie/Spoolman).