idle_timeout: Move timeout handling from toolhead.py to new extras module
Move the "motor_off_timeout" tracking to a new module in the extras/ directory. This makes it easier to customize the idle timeout behavior. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
0025fbf10d
commit
acefe26e0f
|
@ -165,6 +165,17 @@
|
||||||
# default is 120.
|
# 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
|
# Multi-stepper axes. On a cartesian style printer, the stepper
|
||||||
# controlling a given axis may have additional config blocks defining
|
# controlling a given axis may have additional config blocks defining
|
||||||
# steppers that should be stepped in concert with the primary
|
# steppers that should be stepped in concert with the primary
|
||||||
|
|
|
@ -293,9 +293,6 @@ max_z_accel: 30
|
||||||
# mm/s^2) of movement along the z axis. It limits the acceleration
|
# 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
|
# of the z stepper motor on cartesian printers. The default is to
|
||||||
# use max_accel for max_z_accel.
|
# 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
|
#square_corner_velocity: 5.0
|
||||||
# The maximum velocity (in mm/s) that the toolhead may travel a 90
|
# 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
|
# degree corner at. A non-zero value can reduce changes in extruder
|
||||||
|
|
|
@ -216,5 +216,7 @@ max_velocity: 500
|
||||||
max_accel: 3000
|
max_accel: 3000
|
||||||
max_z_velocity: 100
|
max_z_velocity: 100
|
||||||
max_z_accel: 50
|
max_z_accel: 50
|
||||||
|
|
||||||
|
[idle_timeout]
|
||||||
# high motor off time so I don't have to relevel gantry often
|
# high motor off time so I don't have to relevel gantry often
|
||||||
motor_off_time: 6000
|
timeout: 6000
|
||||||
|
|
|
@ -71,9 +71,11 @@ kinematics: delta
|
||||||
max_velocity: 500
|
max_velocity: 500
|
||||||
max_accel: 3000
|
max_accel: 3000
|
||||||
max_z_velocity: 150
|
max_z_velocity: 150
|
||||||
motor_off_time: 360
|
|
||||||
delta_radius: 99.8
|
delta_radius: 99.8
|
||||||
|
|
||||||
|
[idle_timeout]
|
||||||
|
timeout: 360
|
||||||
|
|
||||||
#[delta_calibrate]
|
#[delta_calibrate]
|
||||||
#radius: 50
|
#radius: 50
|
||||||
#manual_probe:
|
#manual_probe:
|
||||||
|
|
|
@ -80,11 +80,13 @@ kinematics: delta
|
||||||
max_velocity: 200
|
max_velocity: 200
|
||||||
max_accel: 3000
|
max_accel: 3000
|
||||||
max_z_velocity: 200
|
max_z_velocity: 200
|
||||||
motor_off_time: 360
|
|
||||||
delta_radius: 115
|
delta_radius: 115
|
||||||
# if you want to DELTA_CALIBRATE you may need that
|
# if you want to DELTA_CALIBRATE you may need that
|
||||||
#minimum_z_position: -5
|
#minimum_z_position: -5
|
||||||
|
|
||||||
|
[idle_timeout]
|
||||||
|
timeout: 360
|
||||||
|
|
||||||
#[delta_calibrate]
|
#[delta_calibrate]
|
||||||
#radius: 115
|
#radius: 115
|
||||||
#manual_probe:
|
#manual_probe:
|
||||||
|
|
|
@ -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)
|
|
@ -231,11 +231,7 @@ class ToolHead:
|
||||||
self.idle_flush_print_time = 0.
|
self.idle_flush_print_time = 0.
|
||||||
self.flush_timer = self.reactor.register_timer(self._flush_handler)
|
self.flush_timer = self.reactor.register_timer(self._flush_handler)
|
||||||
self.move_queue.set_flush_time(self.buffer_time_high)
|
self.move_queue.set_flush_time(self.buffer_time_high)
|
||||||
# Motor off tracking
|
self.printer.try_load_module(config, "idle_timeout")
|
||||||
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)
|
|
||||||
# Setup iterative solver
|
# Setup iterative solver
|
||||||
ffi_main, ffi_lib = chelper.get_ffi()
|
ffi_main, ffi_lib = chelper.get_ffi()
|
||||||
self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free)
|
self.cmove = ffi_main.gc(ffi_lib.move_alloc(), ffi_lib.free)
|
||||||
|
@ -266,7 +262,6 @@ class ToolHead:
|
||||||
if not self.sync_print_time:
|
if not self.sync_print_time:
|
||||||
return self.print_time
|
return self.print_time
|
||||||
self.sync_print_time = False
|
self.sync_print_time = False
|
||||||
self.need_motor_off = True
|
|
||||||
est_print_time = self.mcu.estimated_print_time(self.reactor.monotonic())
|
est_print_time = self.mcu.estimated_print_time(self.reactor.monotonic())
|
||||||
if est_print_time + self.buffer_time_start > self.print_time:
|
if est_print_time + self.buffer_time_start > self.print_time:
|
||||||
self.print_time = est_print_time + self.buffer_time_start
|
self.print_time = est_print_time + self.buffer_time_start
|
||||||
|
@ -329,19 +324,6 @@ class ToolHead:
|
||||||
logging.exception("Exception in flush_handler")
|
logging.exception("Exception in flush_handler")
|
||||||
self.printer.invoke_shutdown("Exception in flush_handler")
|
self.printer.invoke_shutdown("Exception in flush_handler")
|
||||||
return self.reactor.NEVER
|
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
|
# Movement commands
|
||||||
def get_position(self):
|
def get_position(self):
|
||||||
return list(self.commanded_pos)
|
return list(self.commanded_pos)
|
||||||
|
@ -374,7 +356,6 @@ class ToolHead:
|
||||||
for ext in kinematics.extruder.get_printer_extruders(self.printer):
|
for ext in kinematics.extruder.get_printer_extruders(self.printer):
|
||||||
ext.motor_off(last_move_time)
|
ext.motor_off(last_move_time)
|
||||||
self.dwell(STALL_TIME)
|
self.dwell(STALL_TIME)
|
||||||
self.need_motor_off = False
|
|
||||||
logging.debug('; Max time of %f', last_move_time)
|
logging.debug('; Max time of %f', last_move_time)
|
||||||
def wait_moves(self):
|
def wait_moves(self):
|
||||||
self._flush_lookahead()
|
self._flush_lookahead()
|
||||||
|
@ -402,15 +383,17 @@ class ToolHead:
|
||||||
return is_active, "print_time=%.3f buffer_time=%.3f print_stall=%d" % (
|
return is_active, "print_time=%.3f buffer_time=%.3f print_stall=%d" % (
|
||||||
self.print_time, max(buffer_time, 0.), self.print_stall)
|
self.print_time, max(buffer_time, 0.), self.print_stall)
|
||||||
def get_status(self, eventtime):
|
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:
|
if buffer_time > -1. or not self.sync_print_time:
|
||||||
status = "Printing"
|
status = "Printing"
|
||||||
elif self.need_motor_off:
|
|
||||||
status = "Ready"
|
|
||||||
else:
|
else:
|
||||||
status = "Idle"
|
status = "Ready"
|
||||||
printing_time = self.print_time - self.last_print_start_time
|
return { 'status': status, 'print_time': print_time,
|
||||||
return {'status': status, 'printing_time': printing_time}
|
'estimated_print_time': estimated_print_time,
|
||||||
|
'printing_time': print_time - last_print_start_time }
|
||||||
def printer_state(self, state):
|
def printer_state(self, state):
|
||||||
if state == 'shutdown':
|
if state == 'shutdown':
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue