from __future__ import absolute_import from celery.task import Task import majordome from scheduler.models import Scheduler from pyrosapp.models import * from decimal import Decimal import math import itertools class scheduling(Task): def run(self, first_schedule=False, alert=False): '''First, we delete scheduled sequences (and plans in case of alert) ''' if alert is True: majordome.TaskManager.delete_pending_alert() else: majordome.TaskManager.delete_pending_routine() Log.objects.create(agent='Scheduler', message='Start schedule') self.scheduler = Scheduler() if first_schedule is True: self.determine_schedule_limits() self.scheduler.make_schedule(first_schedule) schedule = Schedule.objects.order_by("-created")[0] shs_list = schedule.shs.filter(status=Sequence.PENDING) Log.objects.create(agent='Scheduler', message='Scheduling finished') ''' We create an execute_sequence task for every scheduled sequence ''' for shs in shs_list: res = majordome.tasks.execute_sequence.delay(shs.pk) TaskId.objects.create(task_id=res.id, task="execute_sequence") def determine_schedule_limits(self): sequences = Sequence.objects.all() ''' Find the most recurrent night in all sequences ''' days = {} for sequence in sequences: truncated = math.floor(float(sequence.jd1)) if truncated in days.keys(): days[truncated] += 1 else: days[truncated] = 1 maximum_truncated = max(days.keys(), key=(lambda key: days[key])) ''' Kick all the sequences not in this night ''' sequences = [sequence for sequence in sequences if math.floor( float(sequence.jd1)) == maximum_truncated] ''' Set schedule limits as the smallest JD1 and the biggest JD2 ''' plan_start = -1 plan_end = -1 for sequence in sequences: if plan_start == -1 or sequence.jd1 < plan_start: plan_start = sequence.jd1 if plan_end == -1 or sequence.jd2 > plan_end: plan_end = sequence.jd2 self.scheduler.set_night_limits(Decimal(plan_start), Decimal(plan_end))