mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-25 16:38:36 +01:00
28f4113f2f
Timer was not accurate as it was depending on the asyncio.sleep function which is most liklely not exactly one second depending on other functions running in parallel. Now the timer is comparable to cbpi3 where it runs until an end time is reached. This is to address issue #66 and has been tested
71 lines
2.1 KiB
Python
71 lines
2.1 KiB
Python
import time
|
|
import asyncio
|
|
import math
|
|
|
|
|
|
class Timer(object):
|
|
|
|
def __init__(self, timeout, on_done = None, on_update = None) -> None:
|
|
super().__init__()
|
|
self.timeout = timeout
|
|
self._timemout = self.timeout
|
|
self._task = None
|
|
self._callback = on_done
|
|
self._update = on_update
|
|
self.start_time = None
|
|
self.end_time = None
|
|
|
|
def done(self, task):
|
|
if self._callback is not None:
|
|
asyncio.create_task(self._callback(self))
|
|
|
|
async def _job(self):
|
|
self.start_time = int(time.time())
|
|
self.end_time = self.start_time + int(round(self._timemout, 0))
|
|
self.count = self.end_time - self.start_time
|
|
try:
|
|
while self.count > 0:
|
|
self.count = (self.end_time - int(time.time()))
|
|
if self._update is not None:
|
|
await self._update(self,self.count)
|
|
await asyncio.sleep(1)
|
|
except asyncio.CancelledError:
|
|
end = int(time.time())
|
|
duration = end - self.start_time
|
|
self._timemout = self._timemout - duration
|
|
|
|
async def add(self, seconds):
|
|
self.end_time = self.end_time + seconds
|
|
|
|
def start(self):
|
|
self._task = asyncio.create_task(self._job())
|
|
self._task.add_done_callback(self.done)
|
|
|
|
async def stop(self):
|
|
if self._task and self._task.done() is False:
|
|
self._task.cancel()
|
|
await self._task
|
|
|
|
def reset(self):
|
|
if self.is_running is True:
|
|
return
|
|
self._timemout = self.timeout
|
|
|
|
def is_running(self):
|
|
return not self._task.done()
|
|
|
|
def set_time(self,timeout):
|
|
if self.is_running is True:
|
|
return
|
|
self.timeout = timeout
|
|
|
|
def get_time(self):
|
|
return self.format_time(int(round(self._timemout,0)))
|
|
|
|
@classmethod
|
|
def format_time(cls, time):
|
|
pattern = '{0:02d}:{1:02d}:{2:02d}'
|
|
seconds = time % 60
|
|
minutes = math.floor(time / 60) % 60
|
|
hours = math.floor(time / 3600)
|
|
return pattern.format(hours, minutes, seconds)
|