Use new generic TypedQueue for send queue and command queue
That way no M105 cascades can be triggered by the M105 polling timer (or the M27 polling timer). Adjusted logging output to make clear which queue rejected typed entry. Made timeout handler send M105 with type "temperature" as well to make sure we don't suddenly have two M105 directly after each other in the send_queue, one from the polling timer, one from the timeout handler. Fixes #1275
This commit is contained in:
parent
cbaf848711
commit
baab1ce70a
1 changed files with 12 additions and 42 deletions
|
|
@ -24,7 +24,8 @@ from octoprint.settings import settings, default_settings
|
|||
from octoprint.events import eventManager, Events
|
||||
from octoprint.filemanager import valid_file_type
|
||||
from octoprint.filemanager.destinations import FileDestinations
|
||||
from octoprint.util import get_exception_string, sanitize_ascii, filter_non_ascii, CountedEvent, RepeatedTimer, to_unicode, bom_aware_open
|
||||
from octoprint.util import get_exception_string, sanitize_ascii, filter_non_ascii, CountedEvent, RepeatedTimer, \
|
||||
to_unicode, bom_aware_open, TypedQueue, TypeAlreadyInQueue
|
||||
|
||||
try:
|
||||
import _winreg
|
||||
|
|
@ -214,7 +215,7 @@ class MachineCom(object):
|
|||
self._temp = {}
|
||||
self._bedTemp = None
|
||||
self._tempOffsets = dict()
|
||||
self._commandQueue = queue.Queue()
|
||||
self._command_queue = TypedQueue()
|
||||
self._currentZ = None
|
||||
self._heatupWaitStartTime = None
|
||||
self._heatupWaitTimeLost = 0.0
|
||||
|
|
@ -533,7 +534,10 @@ class MachineCom(object):
|
|||
return
|
||||
|
||||
if self.isPrinting() and not self.isSdFileSelected():
|
||||
self._commandQueue.put((cmd, cmd_type))
|
||||
try:
|
||||
self._command_queue.put((cmd, cmd_type), item_type=cmd_type)
|
||||
except TypeAlreadyInQueue as e:
|
||||
self._logger.debug("Type already in command queue: " + e.type)
|
||||
elif self.isOperational() or force:
|
||||
self._sendCommand(cmd, cmd_type=cmd_type)
|
||||
|
||||
|
|
@ -1240,7 +1244,7 @@ class MachineCom(object):
|
|||
|
||||
else:
|
||||
self._log("Communication timeout while printing, trying to trigger response from printer. " + general_message)
|
||||
self._sendCommand("M105")
|
||||
self._sendCommand("M105", cmd_type="temperature")
|
||||
self._clear_to_send.set()
|
||||
|
||||
return
|
||||
|
|
@ -1332,11 +1336,11 @@ class MachineCom(object):
|
|||
# from the queue, we'll send the second (if there is one). We do not
|
||||
# want to get stuck here by throwing away commands.
|
||||
while True:
|
||||
if self._commandQueue.empty() or self.isStreaming():
|
||||
if self._command_queue.empty() or self.isStreaming():
|
||||
# no command queue or irrelevant command queue => return
|
||||
return False
|
||||
|
||||
entry = self._commandQueue.get()
|
||||
entry = self._command_queue.get()
|
||||
if isinstance(entry, tuple):
|
||||
if not len(entry) == 2:
|
||||
# something with that entry is broken, ignore it and fetch
|
||||
|
|
@ -1691,9 +1695,9 @@ class MachineCom(object):
|
|||
"""
|
||||
|
||||
try:
|
||||
self._send_queue.put((command, linenumber, command_type))
|
||||
self._send_queue.put((command, linenumber, command_type), item_type=command_type)
|
||||
except TypeAlreadyInQueue as e:
|
||||
self._logger.debug("Type already in queue: " + e.type)
|
||||
self._logger.debug("Type already in send queue: " + e.type)
|
||||
|
||||
def _send_loop(self):
|
||||
"""
|
||||
|
|
@ -2269,40 +2273,6 @@ class StreamingGcodeFileInformation(PrintingGcodeFileInformation):
|
|||
return process_gcode_line(line)
|
||||
|
||||
|
||||
class TypedQueue(queue.Queue):
|
||||
|
||||
def __init__(self, maxsize=0):
|
||||
queue.Queue.__init__(self, maxsize=maxsize)
|
||||
self._lookup = []
|
||||
|
||||
def _put(self, item):
|
||||
if isinstance(item, tuple) and len(item) == 3:
|
||||
cmd, line, cmd_type = item
|
||||
if cmd_type is not None:
|
||||
if cmd_type in self._lookup:
|
||||
raise TypeAlreadyInQueue(cmd_type, "Type {cmd_type} is already in queue".format(**locals()))
|
||||
else:
|
||||
self._lookup.append(cmd_type)
|
||||
|
||||
queue.Queue._put(self, item)
|
||||
|
||||
def _get(self):
|
||||
item = queue.Queue._get(self)
|
||||
|
||||
if isinstance(item, tuple) and len(item) == 3:
|
||||
cmd, line, cmd_type = item
|
||||
if cmd_type is not None and cmd_type in self._lookup:
|
||||
self._lookup.remove(cmd_type)
|
||||
|
||||
return item
|
||||
|
||||
|
||||
class TypeAlreadyInQueue(Exception):
|
||||
def __init__(self, t, *args, **kwargs):
|
||||
Exception.__init__(self, *args, **kwargs)
|
||||
self.type = t
|
||||
|
||||
|
||||
def get_new_timeout(type, intervals):
|
||||
now = time.time()
|
||||
return now + intervals.get(type, 0.0)
|
||||
|
|
|
|||
Loading…
Reference in a new issue