Skip to content

feat: add auxiliary part cooling fan support - #805

Open
ndotzbgt wants to merge 6 commits into
Frix-x:mainfrom
ndotzbgt:feat/aux-fan-part-cooling
Open

feat: add auxiliary part cooling fan support#805
ndotzbgt wants to merge 6 commits into
Frix-x:mainfrom
ndotzbgt:feat/aux-fan-part-cooling

Conversation

@ndotzbgt

Copy link
Copy Markdown

Summary

Adds an independently controlled secondary part cooling fan (e.g. the OrcaSlicer "Auxiliary Part Cooling Fan", addressed as M106 P2 / M107 P2), complementing the existing PART_FAN.

Changes

  • Hardware configs (config/hardware/fans/): aux_fan.cfg and aux_fan_tachometer.cfg (the latter adds AUX_FAN_TACHO monitoring with the same safety checks as the base fans). Wired pins use the new AUX_FAN / AUX_FAN_TACHO board_pins aliases.
  • Control macros (macros/hardware_functions/aux_fan.cfg): START_AUX_FAN / STOP_AUX_FAN, a delayed stop macro, the tachometer background check loop, and an M106 / M107 override that forwards P2 to the aux fan and keeps P0 / bare calls fully compatible with existing slicers.
  • Print flow integration:
    • start_print: vent the chamber if it is above the configured temperature before heating, and optionally spread heat during the soak.
    • end_print / cancel_print: optional post-print run-down to cool the bed faster and help recirculating filters/exhaust.
    • control: clean shutdown on PRINT_STOP.
  • Variables & docs: new variable_aux_fan_* settings in variables.cfg, include lines in printer.cfg, and AUX_FAN / AUX_FAN_TACHO pinout documentation.

Validation

Added a CI pipeline: tests/lint_jinja.py syntax-checks every templated block with Klipper's own Jinja2 environment, and tests/config_check.py assembles a full reference config and loads it with a real klippy (standard and aux-fan-tachometer variants), run by .github/workflows/validate.yml.

Verified locally: 279/279 templates pass, both klippy config loads pass (only the expected "no MCU connected" step fails), and an injected broken template fails the checks.

Enabling

Uncomment [include config/hardware/fans/aux_fan.cfg] (or aux_fan_tachometer.cfg) in user_templates/printer.cfg, define AUX_FAN (and optionally AUX_FAN_TACHO) pins in mcu.cfg, and tune the variable_aux_fan_* settings in user_templates/variables.cfg.

Add an independently controlled secondary part cooling fan (e.g. OrcaSlicer
"Auxiliary Part Cooling Fan"):

- config/hardware/fans/aux_fan.cfg / aux_fan_tachometer.cfg with an
  optional tachometer safety check
- START_AUX_FAN / STOP_AUX_FAN macros plus M106/M107 P2 bridge for
  OrcaSlicer compatibility
- integration in start/end/cancel print and control macros:
  chamber venting, heatsoak spread, and post-print run-down cooling
- new aux fan variables and pinout documentation

Also add a config validation pipeline for CI:
- tests/lint_jinja.py reusing Klipper's exact Jinja2 environment to
  syntax-check templated macro blocks
- tests/config_check.py assembling a full reference config and loading
  it with a real klippy (standard + tachometer variants)
- .github/workflows/validate.yml running both
@mjonuschat

Copy link
Copy Markdown
Collaborator

Thank you for your contribution. I see a few problems with this PR:

  1. Separation of concerns, it's doing too much. You've added the aux fan feature, a jinja template linter, a config checker and a CI pipeline under the guise of the aux fan. These should should be at least two, maybe three PRs. Especially given how heavy the config checker is.
  2. There's a number of bugs in the aux fan implementation:
    1. fan monitoring seems to get disable before later end print block that runs the fan for a while
    2. The M106 rename only works when the user included a [fan] block - that is a separate and optional component - hotends like the Chube conduction don't require one, so this is brittle
    3. aux_fan_soak_speed seems to conflict the the hardcoded min_rpm
    4. there's a disconnect between _MODULE_HEATSOAK_BED and _MODULE_HEATSOAK_CHAMBER - they are independent, the fan might never get stopped
    5. CURRENT_CHAMBER_TEMP > aux_fan_vent_temp triggers on room temp with the current defaults, leading to a 2 min delay for everyone, no matter if they opted in.
    6. the start routinge also seems to skip tach monitoring

haze added 2 commits August 15, 2026 15:22
…atsoak safety

- Re-enable tach monitoring after end-print/cancel run-down fan starts
- Replace M106/M107 rename_existing with SET_FAN_SPEED + 'fan' in printer guard (no [fan] dependency)
- Re-enable tach monitoring before chamber vent in START_PRINT
- Add aux_fan_vent_temp > 0 guard to prevent room temp false trigger
- Stop aux fan at end of _MODULE_HEATSOAK_BED as safety net
- Clean up _STOP_AUX_FAN_DELAYED to stop tach loop
- Fix variable ordering in _AUX_FAN_CHECK
…om all [fan] configs

Moves the M106/M107 OrcaSlicer P2 bridge to a separate file (fan_bridge.cfg)
that uses rename_existing (required by Klipper for command overrides) and is
included only from config files that define [fan]. This includes:
  - config/hardware/fans/part_fan.cfg
  - config/hardware/fans/part_fan_tachometer.cfg
  - All 25 toolhead board templates that define [fan]

Users without [fan] (e.g. Chube conduction) no longer get a config load error
from rename_existing. Toolhead board users retain P2 bridge support.
The bridge also checks aux_fan_enabled before routing P2, so it's safe to
include even when no aux fan is configured.
@mjonuschat

Copy link
Copy Markdown
Collaborator

Hey, it looks like there are still some of the bugs I mentioned earlier open in this pull request and the new design with every file that has a [fan] section requiring an include is quite brittle and a maintenance burden for every future board we want to add.

And same as the other changes you had in before, the axis twist compensation needs to be in a separate PR

…rtional min_rpm

- Re-enable tach monitoring BEFORE starting the post-print/cancel aux
  fan so it is monitored from the moment it spins up (was disabled in
  _MODULE_TURN_OFF_FANS and only re-enabled after the fan was running)
- Add fallback M106/M107 macros in aux_fan.cfg that route OrcaSlicer
  P2 commands to SET_FAN_SPEED and forward P0/bare to M106.1/M107.1
  when fan_bridge.cfg is loaded, or silently ignore otherwise. This makes
  the M106 bridge work on machines without a [fan] section (e.g. Chube
  conduction hotends) where fan_bridge.cfg was never included
- Scale _AUX_FAN_CHECK min_rpm proportionally with target fan speed
  (1000 RPM at full, 200 RPM floor) so low aux_fan_soak_speed values
  don't false-positive and cancel the print
- Both standard and tachometer config_check variants pass
@ndotzbgt
ndotzbgt force-pushed the feat/aux-fan-part-cooling branch from a7a5377 to 933109c Compare August 22, 2026 03:08
ndotzbgt and others added 2 commits August 22, 2026 10:13
Remove the fan_bridge.cfg include from all 25 toolhead board templates.
The fallback M106/M107 in aux_fan.cfg now handle OrcaSlicer P2 routing
for all configurations. fan_bridge.cfg (with rename_existing) is only
included from part_fan.cfg/part_fan_tachometer.cfg, where [fan] is
always present.

Toolhead board users who also need bare M106/M107 forwarding to the
native part fan can add a one-line include in their printer.cfg.
Document this in fan_bridge.cfg, aux_fan.cfg, and the printer.cfg
template.

Addresses maintainer feedback about brittleness and maintenance burden
of requiring every [fan]-defining file to include fan_bridge.cfg.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants