from __future__ import absolute_import from celery.task import Task import observation_manager from common.models import * from devices import Telescope as Tel import time import scheduler from decimal import Decimal TIMESTAMP_JD = 2440587.500000 DAILY_SECOND = 1 / 86400 MAX_WAIT = 180 class execute_sequence(Task): ''' Task to handle the execution of ONE sequence It receives the shs' id in parameter. It prepairs the instruments and cut the sequence in plan. Then the execute_plan tasks are created. If possible, it advances the sequence start. If the sequence can't start within MAX_WAIT seconds, it relaunches a scheduling ''' def run(self, shs_pk): # on ne supprime JAMAIS un séquence en cours, donc je peux la virer des tasks dès le début TaskId.objects.filter(task_id=self.request.id).delete() shs = ScheduleHasSequences.objects.get(pk=shs_pk) sequence = shs.sequence if sequence.status != Sequence.OBSERVABLE: return message = 'Start sequence ' + str(sequence.pk) + ' execution' Log.objects.create(agent='Majordome', message=message) print("execute_sequence : ", sequence.pk) countdown = self.get_countdown(shs, sequence) if countdown > MAX_WAIT * DAILY_SECOND: scheduler.tasks.scheduling.delay(first_schedule=True, alert=False) # TODO : changer le first_schedule à False return tel = Tel.TelescopeController() tel.set("SPEED", 10.0, 10.0, 10.0) tel.set("COORDS", 104.0, 12.0, 88.0) tel.set("COORDS_FRAME", "Radec") tel.set("TRACKING_SPEED", 0.3, 0.3, 0.3) tel.set("ACCEL", 1.0, 1.0, 1.0) tel.set("ROTATOR", "Tracking") tel.set("FOCUS", 23562.0) tel.set("MOVE_MODE", "GotoTrack") tel.do("START") countdown = 1 # TODO: à virer, juste pour pouvoir tester plans_results = [] if sequence.albums.filter(detector__device__name="Cagire").exists(): for plan in sequence.albums.get(detector__device__name="Cagire").plans.all(): res = observation_manager.tasks.execute_plan_nir.apply_async((plan.id, countdown)) TaskId.objects.create(task_id=res.id, task="execute_plan") plans_results.append(res) if sequence.albums.filter(detector__device__name="Visible camera").exists(): for plan in sequence.albums.get(detector__device__name="Visible camera").plans.all(): res = observation_manager.tasks.execute_plan_vis.apply_async((plan.id, countdown)) TaskId.objects.create(task_id=res.id, task="execute_plan") plans_results.append(res) shs.status = Sequence.EXECUTING sequence.status = Sequence.EXECUTING shs.save() sequence.save() for plan_result in plans_results: try: while plan_result.ready() == False: print("not finished") time.sleep(4) print("result : %s " % (plan_result.status,)) except Exception as e: print("exception : %s" % (str(e),)) shs.status = Sequence.CANCELLED shs.save() sequence.status = Sequence.CANCELLED sequence.save() return shs.status = Sequence.EXECUTED sequence.status = Sequence.EXECUTED shs.save() sequence.save() message = 'Finished sequence ' + str(sequence.pk) + ' execution' Log.objects.create(agent='Majordome', message=message) def get_countdown(self, shs, sequence): """ Gets the time before the expected start of the execution. If it is > 10s, tries to get the sequence ahead according the JD1 """ countdown = 0 current_time = Decimal(time.time() / 86400 + TIMESTAMP_JD) time_before_exec = shs.tsp - current_time if time_before_exec > 10 * DAILY_SECOND: time_before_jd1 = sequence.jd1 - current_time if time_before_jd1 < 0: pass elif time_before_jd1 < time_before_exec: countdown = time_before_jd1 else: countdown = time_before_exec return countdown class system_pause(Task): ''' Task called by the monitoring in case of problem. It stops the system and the instruments. ''' def run(self): time.sleep(5) print("system_pause") class system_restart(Task): ''' Task called by the monitoring when there is no more problem. Should just make a scheduling. ''' def run(self): time.sleep(5) print("system_restart") class change_obs_conditions(Task): ''' Task called by the monitoring when the obs condition have changed. It reads them in the DB and changes the sequences status in consequence. If needed, relaunches a scheduling ''' def run(self): # important : penser à rendre les quotas aux users time.sleep(5) print("change_obs_conditions")