Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/G-Codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -606,12 +606,16 @@ temperatures at different layers.
### [fan_generic]

The following command is available when a
[fan_generic config section](Config_Reference.md#fan_generic) is
enabled.
[fan_generic](Config_Reference.md#fan_generic)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably needs to be reflowed?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by reflowed here? (apologies for the ignorance)

or
[heater_fan](Config_Reference.md#heater_fan)
config section is enabled.

#### SET_FAN_SPEED
`SET_FAN_SPEED FAN=config_name SPEED=<speed>` This command sets the
speed of a fan. "speed" must be between 0.0 and 1.0.
For `[heater_fan]` the command does not override the minimum speed set
by the heater when it's on.

### [filament_switch_sensor]

Expand Down
29 changes: 25 additions & 4 deletions klippy/extras/heater_fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@


class PrinterHeaterFan:
cmd_SET_FAN_SPEED_help = "Sets the speed of a fan"

def __init__(self, config):
self.printer = config.get_printer()
self.printer.load_object(config, "heaters")
Expand All @@ -17,10 +19,23 @@ def __init__(self, config):
self.heater_temp = config.getfloat("heater_temp", 50.0)
self.heaters = []
self.fan = fan.Fan(config, default_shutdown_speed=1.0)
self.fan_speed = config.getfloat(
self.enabled_fan_speed = config.getfloat(
"fan_speed", 1.0, minval=0.0, maxval=1.0
)
self.last_speed = 0.0
self.last_gcode_speed = 0.0

# register SET_FAN_SPEED mux command so users can override this fan
self.fan_name = config.get_name().split()[-1]
gcode = self.printer.lookup_object("gcode")
gcode.register_mux_command(
"SET_FAN_SPEED",
"FAN",
self.fan_name,
self.cmd_SET_FAN_SPEED,
desc=self.cmd_SET_FAN_SPEED_help,
)


def handle_ready(self):
pheaters = self.printer.lookup_object("heaters")
Expand All @@ -34,18 +49,24 @@ def get_status(self, eventtime):
return self.fan.get_status(eventtime)

def callback(self, eventtime):
speed = 0.0
speed = self.last_gcode_speed
for heater in self.heaters:
current_temp, target_temp = heater.get_temp(eventtime)
if target_temp or current_temp > self.heater_temp:
speed = self.fan_speed
if (target_temp or current_temp > self.heater_temp) and self.enabled_fan_speed > speed:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here is a bit hard to follow, could we split it over multiple statements or something? I'm having a hard time understanding the interaction between last_gcode_speed and enabled_fan_speed as the code currently stands.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm going to follow up on this as I use this feature all the time and would love moonraker to not freak out about a dirty repo. Having just read through it, last_gcode_speed is always set to the value requested by the SET_FAN_SPEED command, and enabled_fan_speed is the constant speed defined in klipper config files.

In the callback function, the speed variable is now set to last_gcode_speed by default instead of 0. The AND statement in question now checks if the user-requested speed is less than the default enabled_fan_speed. If so, it is invalid, and speed will be overwritten by enabled_fan_speed. However if speed / last_gcode_speed is greater, then it is preserved and set as the fan speed.

Happy to split it up into multiple statements, but it would just be the same statement on the second line.

speed = self.enabled_fan_speed
if speed != self.last_speed:
self.last_speed = speed
curtime = self.printer.get_reactor().monotonic()
print_time = self.fan.get_mcu().estimated_print_time(curtime)
self.fan.set_speed(print_time + PIN_MIN_TIME, speed)
return eventtime + 1.0

# SET_FAN_SPEED can only override this fan speed to a speed higher than the minimum one set by the heater
def cmd_SET_FAN_SPEED(self, gcmd):
self.last_gcode_speed = gcmd.get_float("SPEED", 0.0)
speed = max(self.last_speed, self.last_gcode_speed)
self.fan.set_speed_from_command(speed)


def load_config_prefix(config):
return PrinterHeaterFan(config)
Loading