Added RepeatedTime class to use for repeated tasks
Utilizing it for temperature and sd status polling in comm.py
This commit is contained in:
parent
b3739c10cc
commit
1c1e6b45b6
2 changed files with 70 additions and 12 deletions
|
|
@ -534,6 +534,69 @@ def address_for_client(host, port):
|
|||
except:
|
||||
continue
|
||||
|
||||
class RepeatedTimer(threading.Thread):
|
||||
"""
|
||||
This class represents an action that should be run repeatedly in a predefined interval. It is similar to python's
|
||||
own :class:`threading.Timer` class, but instead of only running once the ``function`` will be run again and again,
|
||||
sleeping the stated ``interval`` in between.
|
||||
|
||||
RepeatedTimers are started, as with threads, by calling their ``start()`` method. The timer can be stopped (in
|
||||
between runs) by calling the :func:`cancel` method. The interval the time waited before execution of a loop may
|
||||
not be exactly the same as the interval specified by the user.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def hello():
|
||||
print("Hello World!")
|
||||
|
||||
t = Timer(1.0, hello)
|
||||
t.start() # prints "Hello World!" every second
|
||||
|
||||
Arguments:
|
||||
interval (float): The interval between each ``function`` call, in seconds.
|
||||
function (callable): The function to call.
|
||||
args (list or tuple): The arguments for the ``function`` call.
|
||||
kwargs (dict): The keyword arguments for the ``function`` call.
|
||||
run_first (boolean): If set to True, the function will be run for the first time *before* the first wait period.
|
||||
If set to False (the default), the function will be run for the first time *after* the first wait period.
|
||||
"""
|
||||
|
||||
def __init__(self, interval, function, args=None, kwargs=None, run_first=False):
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
if args is None:
|
||||
args = []
|
||||
if kwargs is None:
|
||||
kwargs = dict()
|
||||
|
||||
self.interval = interval
|
||||
self.function = function
|
||||
self.finished = threading.Event()
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.run_first = run_first
|
||||
|
||||
def cancel(self):
|
||||
self.finished.set()
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
if self.run_first:
|
||||
# if we are to run the function BEFORE waiting for the first time
|
||||
self.function(*self.args, **self.kwargs)
|
||||
|
||||
# wait, but break if we are cancelled
|
||||
self.finished.wait(self.interval)
|
||||
if self.finished.is_set():
|
||||
return
|
||||
|
||||
if not self.run_first:
|
||||
# if we are to run the function AFTER waiting for the first time
|
||||
self.function(*self.args, **self.kwargs)
|
||||
|
||||
|
||||
class CountedEvent(object):
|
||||
|
||||
def __init__(self, value=0, max=None, name=None):
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ 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
|
||||
from octoprint.util import get_exception_string, sanitize_ascii, filter_non_ascii, CountedEvent, RepeatedTimer
|
||||
from octoprint.util.virtual import VirtualPrinter
|
||||
|
||||
try:
|
||||
|
|
@ -165,8 +165,8 @@ class MachineCom(object):
|
|||
|
||||
self._clear_to_send = CountedEvent(max=10, name="comm.clear_to_send")
|
||||
self._send_queue = TypedQueue()
|
||||
self._sd_status_timer = None
|
||||
self._temperature_timer = None
|
||||
self._sd_status_timer = None
|
||||
|
||||
# hooks
|
||||
self._pluginManager = octoprint.plugin.plugin_manager()
|
||||
|
|
@ -510,7 +510,9 @@ class MachineCom(object):
|
|||
self._currentFile.setFilepos(0)
|
||||
|
||||
self.sendCommand("M24")
|
||||
self._poll_sd_status()
|
||||
|
||||
self._sd_status_timer = RepeatedTimer(get_interval("sdStatus"), self._poll_sd_status, run_first=True)
|
||||
self._sd_status_timer.start()
|
||||
else:
|
||||
line = self._getNext()
|
||||
if line is not None:
|
||||
|
|
@ -1130,10 +1132,6 @@ class MachineCom(object):
|
|||
if self.isOperational() and not self.isStreaming() and not self._blocking_command and not self._heating:
|
||||
self.sendCommand("M105", cmd_type="temperature_poll")
|
||||
|
||||
interval = get_interval("temperature")
|
||||
self._temperature_timer = threading.Timer(interval, self._poll_temperature)
|
||||
self._temperature_timer.start()
|
||||
|
||||
def _poll_sd_status(self):
|
||||
"""
|
||||
Polls the sd printing status after the sd status timeout, re-enqueues itself.
|
||||
|
|
@ -1145,12 +1143,9 @@ class MachineCom(object):
|
|||
if self.isOperational() and self.isSdPrinting() and not self._blocking_command and not self._heating:
|
||||
self.sendCommand("M27", cmd_type="sd_status_poll")
|
||||
|
||||
interval = get_interval("sdStatus")
|
||||
self._sd_status_timer = threading.Timer(interval, self._poll_sd_status)
|
||||
self._sd_status_timer.start()
|
||||
|
||||
def _onConnected(self):
|
||||
self._poll_temperature()
|
||||
self._temperature_timer = RepeatedTimer(get_interval("temperature"), self._poll_temperature, run_first=True)
|
||||
self._temperature_timer.start()
|
||||
|
||||
self._changeState(self.STATE_OPERATIONAL)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue