Shorter timeout during heatup & no scary message on end

Set read timeout on serial port to a much shorter value (default 2.0s)
during a heatup. Firmware should usually send the current temperature
back every second, so if that stops we can consider the heatup to be finished
even if we don't see an ok.

That is important in cases such as SD printing, where we might see a
heatup sequence we didn't trigger ourselves, during which we shouldn't spam
the printer with commands it potentially can't process but after which we
still should take up normal communication again. In case of a heatup sequence
triggered by an SD print we won't see an ok and hence only can now through a
timeout that things are now done printer side. In such a case the user should not
get thrown a scary timeout message in their general direction either.

Solves #1409
This commit is contained in:
Gina Häußge 2016-07-13 17:21:45 +02:00
parent 2cc9631791
commit 937487037a
3 changed files with 45 additions and 13 deletions

View file

@ -16,7 +16,7 @@ from serial import SerialTimeoutException
from octoprint.settings import settings
from octoprint.plugin import plugin_manager
class VirtualPrinter():
class VirtualPrinter(object):
command_regex = re.compile("[GM]\d+")
sleep_regex = re.compile("sleep (\d+)")
sleep_after_regex = re.compile("sleep_after ([GM]\d+) (\d+)")
@ -25,7 +25,7 @@ class VirtualPrinter():
def __init__(self, read_timeout=5.0, write_timeout=10.0):
import logging
self._logger = logging.getLogger("octoprint.plugin.virtual_printer.VirtualPrinter")
self._logger = logging.getLogger("octoprint.plugins.virtual_printer.VirtualPrinter")
self._read_timeout = read_timeout
self._write_timeout = write_timeout
@ -108,6 +108,24 @@ class VirtualPrinter():
return "VIRTUAL(read_timeout={read_timeout},write_timeout={write_timeout},options={options})"\
.format(read_timeout=self._read_timeout, write_timeout=self._write_timeout, options=settings().get(["devel", "virtualPrinter"]))
@property
def timeout(self):
return self._read_timeout
@timeout.setter
def timeout(self, value):
self._logger.debug("Setting read timeout to {}s".format(value))
self._read_timeout = value
@property
def write_timeout(self):
return self._write_timeout
@write_timeout.setter
def write_timeout(self, value):
self._logger.debug("Setting write timeout to {}s".format(value))
self._write_timeout = value
def _clearQueue(self, queue):
try:
while queue.get(block=False):

View file

@ -81,6 +81,7 @@ default_settings = {
"detection": 0.5,
"connection": 10,
"communication": 30,
"heatup": 2,
"temperature": 5,
"sdStatus": 1
},

View file

@ -956,7 +956,10 @@ class MachineCom(object):
if line is None:
break
if line.strip() is not "":
self._timeout = get_new_timeout("communication", self._timeout_intervals)
if self._heating:
self._timeout = get_new_timeout("heatup", self._timeout_intervals)
else:
self._timeout = get_new_timeout("communication", self._timeout_intervals)
##~~ debugging output handling
if line.startswith("//"):
@ -1059,8 +1062,7 @@ class MachineCom(object):
elif ' T:' in line or line.startswith('T:') or ' T0:' in line or line.startswith('T0:') or ((' B:' in line or line.startswith('B:')) and not 'A:' in line):
if not disable_external_heatup_detection and not line.strip().startswith("ok") and not self._heating:
self._logger.debug("Externally triggered heatup detected")
self._heating = True
self._heatupWaitStartTime = time.time()
self._track_heatup()
self._processTemperatures(line)
self._callback.on_comm_temperature_update(self._temp, self._bedTemp)
@ -1259,10 +1261,7 @@ class MachineCom(object):
self._currentTool = self._formerTool
self._formerTool = None
if self._heatupWaitStartTime:
self._heatupWaitTimeLost = self._heatupWaitTimeLost + (time.time() - self._heatupWaitStartTime)
self._heatupWaitStartTime = None
self._heating = False
self._finish_heatup()
if not self._state in (self.STATE_PRINTING, self.STATE_OPERATIONAL, self.STATE_PAUSED):
return
@ -1291,6 +1290,10 @@ class MachineCom(object):
self._resendSameCommand()
self._clear_to_send.set()
elif self._heating:
self._logger.debug("Timeout while in an active heatup, considering heatup to be over then")
self._finish_heatup()
else:
self._log("Communication timeout while printing, trying to trigger response from printer. " + general_message)
self._sendCommand("M105", cmd_type="temperature")
@ -1298,6 +1301,18 @@ class MachineCom(object):
return
def _track_heatup(self):
self._heating = True
self._heatupWaitStartTime = time.time()
self._serial.timeout = settings().getFloat(["serial", "timeout", "heatup"])
def _finish_heatup(self):
if self._heatupWaitStartTime:
self._heatupWaitTimeLost = self._heatupWaitTimeLost + (time.time() - self._heatupWaitStartTime)
self._heatupWaitStartTime = None
self._heating = False
self._serial.timeout = settings().getFloat(["serial", "timeout", "communication"])
def _continue_sending(self):
if self._state == self.STATE_PRINTING:
if not self._sendFromQueue() and not self.isSdPrinting():
@ -2036,15 +2051,13 @@ class MachineCom(object):
pass
def _gcode_M109_sent(self, cmd, cmd_type=None):
self._heatupWaitStartTime = time.time()
self._long_running_command = True
self._heating = True
self._track_heatup()
self._gcode_M104_sent(cmd, cmd_type, wait=True)
def _gcode_M190_sent(self, cmd, cmd_type=None):
self._heatupWaitStartTime = time.time()
self._long_running_command = True
self._heating = True
self._track_heatup()
self._gcode_M140_sent(cmd, cmd_type, wait=True)
def _gcode_M110_sending(self, cmd, cmd_type=None):