Files
supervisor/hassio/misc/scheduler.py
Pascal Vizeli eebe90bd14 Add support for stats & code cleanup (#297)
* Add support for stats & code cleanup

* Add more stats

* Move code into own object

* Add to API

* Update API

* Add error handling

* fix lint

* fix block io
2018-01-07 15:53:54 +01:00

76 lines
2.1 KiB
Python

"""Schedule for HassIO."""
import logging
from datetime import date, datetime, time, timedelta
_LOGGER = logging.getLogger(__name__)
INTERVAL = 'interval'
REPEAT = 'repeat'
CALL = 'callback'
TASK = 'task'
class Scheduler(object):
"""Schedule task inside HassIO."""
def __init__(self, loop):
"""Initialize task schedule."""
self.loop = loop
self._data = {}
self.suspend = False
def register_task(self, coro_callback, interval, repeat=True):
"""Schedule a coroutine.
The coroutien need to be a callback without arguments.
"""
task_id = hash(coro_callback)
# generate data
opts = {
CALL: coro_callback,
INTERVAL: interval,
REPEAT: repeat,
}
# schedule task
self._data[task_id] = opts
self._schedule_task(interval, task_id)
return task_id
def _run_task(self, task_id):
"""Run a scheduled task."""
data = self._data[task_id]
if not self.suspend:
self.loop.create_task(data[CALL]())
if data[REPEAT]:
self._schedule_task(data[INTERVAL], task_id)
else:
self._data.pop(task_id)
def _schedule_task(self, interval, task_id):
"""Schedule a task on loop."""
if isinstance(interval, (int, float)):
job = self.loop.call_later(interval, self._run_task, task_id)
elif isinstance(interval, time):
today = datetime.combine(date.today(), interval)
tomorrow = datetime.combine(
date.today() + timedelta(days=1), interval)
# check if we run it today or next day
if today > datetime.today():
calc = today
else:
calc = tomorrow
job = self.loop.call_at(calc.timestamp(), self._run_task, task_id)
else:
_LOGGER.fatal("Unknow interval %s (type: %s) for scheduler %s",
interval, type(interval), task_id)
# Store job
self._data[task_id][TASK] = job