from apscheduler.schedulers.background import BackgroundScheduler
from pytz import timezone
import ast
import datetime
import logging
class Scheduler:
def __init__(self, network, config):
self.logger = logging.getLogger('hydrobot')
self.network = network
self.config = config
self.apscheduler = BackgroundScheduler()
self.apscheduler.configure(timezone=timezone(config.get("system", "timezone")))
def start(self):
self.apscheduler.start()
self.load_schedules()
def interval_on(self, module, output, timer_off, timer_on, on_duration):
module.set_output(output, 1)
self.apscheduler.get_job(timer_on).reschedule("interval", weeks = on_duration[0], days = on_duration[1], hours = on_duration[2], minutes = on_duration[3], seconds = on_duration[4])
self.apscheduler.get_job(timer_on).resume()
self.apscheduler.get_job(timer_off).pause()
self.logger.info("Turning " + timer_on + "!")
def interval_off(self, module, output, timer_off, timer_on, off_duration):
module.set_output(output, 0)
self.apscheduler.get_job(timer_off).reschedule("interval", weeks = off_duration[0], days = off_duration[1], hours = off_duration[2], minutes = off_duration[3], seconds = off_duration[4])
self.apscheduler.get_job(timer_off).resume()
self.apscheduler.get_job(timer_on).pause()
self.logger.info("Turning " + timer_off + "!")
def add_schedule(self, name, trigger, module_name, output, on_param, off_param):
module = self.network.module_list.lookup_module_by_name(module_name)
if not module == None:
if trigger == "cron":
on_job = self.apscheduler.add_job(module.set_output, trigger, [output, 1], day = on_param[0], day_of_week = on_param[1], hour = on_param[2], minute = on_param[3], second = on_param[4])
off_job = self.apscheduler.add_job(module.set_output, trigger, [output, 0], day = off_param[0], day_of_week = off_param[1], hour = off_param[2], minute = off_param[3], second = off_param[4])
#evalute the current state of the cron trigger and set output on if needed
if on_job.next_run_time > off_job.next_run_time:
module.set_output(output, 1)
else:
module.set_output(output, 0)
if trigger == "interval":
self.apscheduler.add_job(self.interval_on, trigger, [module, output, name + "_off", name + "_on", on_param], id = name + "_off", weeks = off_param[0], days = off_param[1], hours = off_param[2], minutes = off_param[3], seconds = off_param[4])
timer = self.apscheduler.add_job(self.interval_off, trigger, [module, output, name + "_off", name + "_on", off_param], id = name + "_on", weeks = on_param[0], days = on_param[1], hours = on_param[2], minutes = on_param[3], seconds = on_param[4])
timer.pause()
self.interval_on(module, output, name + "_off", name + "_on", on_param)
else:
self.logger.warning("Module not found: " + module_name)
def load_schedules(self):
for section in self.config.sections():
if "timer" in section:
items = self.config.items(section)
for item in items:
if item[0] == "trigger":
trigger = item[1]
if item[0] == "module_name":
module_name = item[1]
if item[0] == "output":
output = item[1]
if item[0] == "on_time":
on_param = ast.literal_eval(item[1])
if item[0] == "off_time":
off_param = ast.literal_eval(item[1])
if item[0] == "on_duration":
on_param = ast.literal_eval(item[1])
if item[0] == "off_duration":
off_param = ast.literal_eval(item[1])
self.add_schedule(section, trigger, module_name, output, on_param, off_param)