CreatBotKlipper/klippy/extras/filament_switch_sensor.py
zkk 5cd9e09192 修改打印中切换喷头 babystep值丢失问题
修改最小挤出温度为100℃ 低于时只警告不停止
修改F430NX切换喷头时候降平台
优化打印中切换喷头不重置挤出量,打印结束时重置挤出量和速度
新增支持P800

Squashed commit of the following:

commit 617b5bd632590bb66e6186952d895fe1a8343f0d
Merge: 530470a41 434e023f3
Author: zkk <1007518571@qq.com>
Date:   Sat Jun 21 14:03:49 2025 +0800

# Conflicts:
#	config/CreatBot_D1000/base.cfg   resolved by 617b5bd632590bb66e6186952d895fe1a8343f0d version
#	config/CreatBot_D1000_V0/base.cfg   resolved by 617b5bd632590bb66e6186952d895fe1a8343f0d version
#	config/CreatBot_D600Pro2/base.cfg   resolved by 617b5bd632590bb66e6186952d895fe1a8343f0d version
#	config/CreatBot_D600Pro2_V0/base.cfg   resolved by 617b5bd632590bb66e6186952d895fe1a8343f0d version
#	config/CreatBot_F430NX/base.cfg   resolved by 617b5bd632590bb66e6186952d895fe1a8343f0d version
#	scripts/graph_mesh.py   resolved by master version
2025-06-21 14:13:20 +08:00

125 lines
5.7 KiB
Python

# Generic Filament Sensor Module
#
# Copyright (C) 2019 Eric Callahan <arksine.code@gmail.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
class RunoutHelper:
def __init__(self, config):
self.name = config.get_name().split()[-1]
self.printer = config.get_printer()
self.reactor = self.printer.get_reactor()
self.gcode = self.printer.lookup_object('gcode')
# Read config
self.runout_pause = config.getboolean('pause_on_runout', True)
if self.runout_pause:
self.printer.load_object(config, 'pause_resume')
self.runout_gcode = self.insert_gcode = None
gcode_macro = self.printer.load_object(config, 'gcode_macro')
if self.runout_pause or config.get('runout_gcode', None) is not None:
self.runout_gcode = gcode_macro.load_template(
config, 'runout_gcode', '')
if config.get('insert_gcode', None) is not None:
self.insert_gcode = gcode_macro.load_template(
config, 'insert_gcode')
self.pause_delay = config.getfloat('pause_delay', .5, above=.0)
self.event_delay = config.getfloat('event_delay', 3., minval=.0)
# Internal state
self.min_event_systime = self.reactor.NEVER
self.filament_present = False
self.sensor_enabled = True
# Register commands and event handlers
self.printer.register_event_handler("klippy:ready", self._handle_ready)
self.gcode.register_mux_command(
"QUERY_FILAMENT_SENSOR", "SENSOR", self.name,
self.cmd_QUERY_FILAMENT_SENSOR,
desc=self.cmd_QUERY_FILAMENT_SENSOR_help)
self.gcode.register_mux_command(
"SET_FILAMENT_SENSOR", "SENSOR", self.name,
self.cmd_SET_FILAMENT_SENSOR,
desc=self.cmd_SET_FILAMENT_SENSOR_help)
def _handle_ready(self):
self.min_event_systime = self.reactor.monotonic() + 2.
def _runout_event_handler(self, eventtime):
# Pausing from inside an event requires that the pause portion
# of pause_resume execute immediately.
pause_prefix = ""
if self.runout_pause:
pause_resume = self.printer.lookup_object('pause_resume')
pause_resume.send_pause_command()
pause_prefix = "PAUSE\n"
self.printer.get_reactor().pause(eventtime + self.pause_delay)
self._exec_gcode(pause_prefix, self.runout_gcode)
def _insert_event_handler(self, eventtime):
self._exec_gcode("", self.insert_gcode)
def _exec_gcode(self, prefix, template):
try:
self.gcode.run_script(prefix + template.render() + "\nM400")
except Exception:
logging.exception("Script running error")
self.min_event_systime = self.reactor.monotonic() + self.event_delay
def note_filament_present(self, eventtime, is_filament_present):
if is_filament_present == self.filament_present:
return
self.filament_present = is_filament_present
if eventtime < self.min_event_systime or not self.sensor_enabled:
# do not process during the initialization time, duplicates,
# during the event delay time, while an event is running, or
# when the sensor is disabled
return
# Determine "printing" status
now = self.reactor.monotonic()
idle_timeout = self.printer.lookup_object("idle_timeout")
is_printing = idle_timeout.get_status(now)["state"] == "Printing"
# Perform filament action associated with status change (if any)
if is_filament_present:
if hasattr(self, 'airpump'):
self.min_event_systime = self.reactor.NEVER
self.reactor.register_callback(self._insert_pump_event_handler)
if not is_printing and self.insert_gcode is not None:
# insert detected
self.min_event_systime = self.reactor.NEVER
logging.info(
"Filament Sensor %s: insert event detected, Time %.2f" %
(self.name, now))
self.reactor.register_callback(self._insert_event_handler)
elif is_printing and self.runout_gcode is not None:
# runout detected
self.min_event_systime = self.reactor.NEVER
logging.info(
"Filament Sensor %s: runout event detected, Time %.2f" %
(self.name, now))
self.reactor.register_callback(self._runout_event_handler)
def get_status(self, eventtime):
return {
"filament_detected": bool(self.filament_present),
"enabled": bool(self.sensor_enabled)}
cmd_QUERY_FILAMENT_SENSOR_help = "Query the status of the Filament Sensor"
def cmd_QUERY_FILAMENT_SENSOR(self, gcmd):
if self.filament_present:
msg = "Filament Sensor %s: filament detected" % (self.name)
else:
msg = "Filament Sensor %s: filament not detected" % (self.name)
gcmd.respond_info(msg)
cmd_SET_FILAMENT_SENSOR_help = "Sets the filament sensor on/off"
def cmd_SET_FILAMENT_SENSOR(self, gcmd):
self.sensor_enabled = gcmd.get_int("ENABLE", 1)
class SwitchSensor:
def __init__(self, config):
printer = config.get_printer()
buttons = printer.load_object(config, 'buttons')
switch_pin = config.get('switch_pin')
buttons.register_debounce_button(switch_pin, self._button_handler
, config)
self.runout_helper = RunoutHelper(config)
self.get_status = self.runout_helper.get_status
def _button_handler(self, eventtime, state):
self.runout_helper.note_filament_present(eventtime, state)
def load_config_prefix(config):
return SwitchSensor(config)