aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/example-extras.cfg11
-rw-r--r--config/example.cfg3
-rw-r--r--config/kit-voron2-2018.cfg4
-rw-r--r--config/printer-anycubic-kossel-2016.cfg4
-rw-r--r--config/printer-anycubic-kossel-plus-2017.cfg4
-rw-r--r--klippy/extras/idle_timeout.py48
-rw-r--r--klippy/toolhead.py35
7 files changed, 77 insertions, 32 deletions
diff --git a/config/example-extras.cfg b/config/example-extras.cfg
index 84d8a05a..e6c0adae 100644
--- a/config/example-extras.cfg
+++ b/config/example-extras.cfg
@@ -165,6 +165,17 @@
# default is 120.
+# Idle timeout. An idle timeout is automatically enabled - add an
+# explicit idle_timeout config section to change the default settings.
+#[idle_timeout]
+#gcode:
+# A list of G-Code commands (one per line) to execute on an idle
+# timeout. The default is to run "M84".
+#timeout: 600
+# Idle time (in seconds) to wait before running the above G-Code
+# commands. The default is 600 seconds.
+
+
# Multi-stepper axes. On a cartesian style printer, the stepper
# controlling a given axis may have additional config blocks defining
# steppers that should be stepped in concert with the primary
diff --git a/config/example.cfg b/config/example.cfg
index d8ca95fa..025f6b71 100644
--- a/config/example.cfg
+++ b/config/example.cfg
@@ -293,9 +293,6 @@ max_z_accel: 30
# mm/s^2) of movement along the z axis. It limits the acceleration
# of the z stepper motor on cartesian printers. The default is to
# use max_accel for max_z_accel.
-#motor_off_time: 600
-# Time (in seconds) of idle time before the printer will try to
-# disable active motors. The default is 600 seconds.
#square_corner_velocity: 5.0
# The maximum velocity (in mm/s) that the toolhead may travel a 90
# degree corner at. A non-zero value can reduce changes in extruder
diff --git a/config/kit-voron2-2018.cfg b/config/kit-voron2-2018.cfg
index 674d1ad4..b48890b7 100644
--- a/config/kit-voron2-2018.cfg
+++ b/config/kit-voron2-2018.cfg
@@ -216,5 +216,7 @@ max_velocity: 500
max_accel: 3000
max_z_velocity: 100
max_z_accel: 50
+
+[idle_timeout]
# high motor off time so I don't have to relevel gantry often
-motor_off_time: 6000
+timeout: 6000
diff --git a/config/printer-anycubic-kossel-2016.cfg b/config/printer-anycubic-kossel-2016.cfg
index d3c50bd1..53ef9f81 100644
--- a/config/printer-anycubic-kossel-2016.cfg
+++ b/config/printer-anycubic-kossel-2016.cfg
@@ -71,9 +71,11 @@ kinematics: delta
max_velocity: 500
max_accel: 3000
max_z_velocity: 150
-motor_off_time: 360
delta_radius: 99.8
+[idle_timeout]
+timeout: 360
+
#[delta_calibrate]
#radius: 50
#manual_probe:
diff --git a/config/printer-anycubic-kossel-plus-2017.cfg b/config/printer-anycubic-kossel-plus-2017.cfg
index 30b8c0d6..cc8b64a3 100644
--- a/config/printer-anycubic-kossel-plus-2017.cfg
+++ b/config/printer-anycubic-kossel-plus-2017.cfg
@@ -80,11 +80,13 @@ kinematics: delta
max_velocity: 200
max_accel: 3000
max_z_velocity: 200
-motor_off_time: 360
delta_radius: 115
# if you want to DELTA_CALIBRATE you may need that
#minimum_z_position: -5
+[idle_timeout]
+timeout: 360
+
#[delta_calibrate]
#radius: 115
#manual_probe:
diff --git a/klippy/extras/idle_timeout.py b/klippy/extras/idle_timeout.py
new file mode 100644
index 00000000..ac91cbcf
--- /dev/null
+++ b/klippy/extras/idle_timeout.py
@@ -0,0 +1,48 @@
+# Support for disabling the printer on an idle timeout
+#
+# Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
+#
+# This file may be distributed under the terms of the GNU GPLv3 license.
+
+DEFAULT_IDLE_GCODE = """
+M84
+"""
+
+class IdleTimeout:
+ def __init__(self, config):
+ self.printer = config.get_printer()
+ self.toolhead = None
+ self.last_timeout = 0.
+ self.idle_timeout = config.getfloat('timeout', 600., above=0.)
+ self.idle_script = config.get('gcode', DEFAULT_IDLE_GCODE)
+ def printer_state(self, state):
+ if state == 'ready':
+ self.toolhead = self.printer.lookup_object('toolhead')
+ reactor = self.printer.get_reactor()
+ reactor.register_timer(self.timeout_handler, reactor.NOW)
+ def run_idle_script(self):
+ gcode = self.printer.lookup_object('gcode')
+ for line in self.idle_script.split('\n'):
+ try:
+ res = gcode.process_batch(line)
+ except:
+ break
+ if not res:
+ # Raced with incoming g-code commands
+ return
+ self.last_timeout = self.toolhead.get_last_move_time()
+ def timeout_handler(self, eventtime):
+ info = self.toolhead.get_status(eventtime)
+ print_time = info['print_time']
+ status = info['status']
+ if print_time <= self.last_timeout or status == 'Printing':
+ return eventtime + self.idle_timeout
+ estimated_print_time = info['estimated_print_time']
+ elapsed_time = estimated_print_time - print_time
+ if elapsed_time < self.idle_timeout:
+ return eventtime + self.idle_timeout - elapsed_time
+ self.run_idle_script()
+ return eventtime + 1.
+
+def load_config(config):
+ return IdleTimeout(config)
diff --git a/klippy/toolhead.py b/klippy/toolhead.py
index 94ee0891..c8a48fa8 100644
--- a/klippy/toolhead.py
+++ b/klippy/toolhead.py
@@ -231,11 +231,7 @@ class ToolHead:
self.idle_flush_print_time = 0.
self.flush_timer = self.reactor.register_timer(self._flush_handler)
self.move_queue.set_flush_time(self.buffer_time_high)
- # Motor off tracking
- self.need_motor_off = False
- self.motor_off_time = config.getfloat('motor_off_time', 600., above=0.)
- self.motor_off_timer = self.reactor.register_timer(
- self._motor_off_handler, self.reactor.NOW)
+ self.printer.try_load_module(config, "idle_timeout")
# Setup iterative solver
ffi_main, ffi_lib = chelper.get_ffi()
self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free)
@@ -266,7 +262,6 @@ class ToolHead:
if not self.sync_print_time:
return self.print_time
self.sync_print_time = False
- self.need_motor_off = True
est_print_time = self.mcu.estimated_print_time(self.reactor.monotonic())
if est_print_time + self.buffer_time_start > self.print_time:
self.print_time = est_print_time + self.buffer_time_start
@@ -329,19 +324,6 @@ class ToolHead:
logging.exception("Exception in flush_handler")
self.printer.invoke_shutdown("Exception in flush_handler")
return self.reactor.NEVER
- # Motor off timer
- def _motor_off_handler(self, eventtime):
- if not self.need_motor_off or not self.sync_print_time:
- return eventtime + self.motor_off_time
- elapsed_time = self.mcu.estimated_print_time(eventtime) - self.print_time
- if elapsed_time < self.motor_off_time:
- return eventtime + self.motor_off_time - elapsed_time
- try:
- self.motor_off()
- except:
- logging.exception("Exception in motor_off_handler")
- self.printer.invoke_shutdown("Exception in motor_off_handler")
- return eventtime + self.motor_off_time
# Movement commands
def get_position(self):
return list(self.commanded_pos)
@@ -374,7 +356,6 @@ class ToolHead:
for ext in kinematics.extruder.get_printer_extruders(self.printer):
ext.motor_off(last_move_time)
self.dwell(STALL_TIME)
- self.need_motor_off = False
logging.debug('; Max time of %f', last_move_time)
def wait_moves(self):
self._flush_lookahead()
@@ -402,15 +383,17 @@ class ToolHead:
return is_active, "print_time=%.3f buffer_time=%.3f print_stall=%d" % (
self.print_time, max(buffer_time, 0.), self.print_stall)
def get_status(self, eventtime):
- buffer_time = self.print_time - self.mcu.estimated_print_time(eventtime)
+ print_time = self.print_time
+ estimated_print_time = self.mcu.estimated_print_time(eventtime)
+ last_print_start_time = self.last_print_start_time
+ buffer_time = print_time - estimated_print_time
if buffer_time > -1. or not self.sync_print_time:
status = "Printing"
- elif self.need_motor_off:
- status = "Ready"
else:
- status = "Idle"
- printing_time = self.print_time - self.last_print_start_time
- return {'status': status, 'printing_time': printing_time}
+ status = "Ready"
+ return { 'status': status, 'print_time': print_time,
+ 'estimated_print_time': estimated_print_time,
+ 'printing_time': print_time - last_print_start_time }
def printer_state(self, state):
if state == 'shutdown':
try: