-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/majordome/tasks.py b/src/majordome/tasks.py
index f0d0e1a..51d5759 100644
--- a/src/majordome/tasks.py
+++ b/src/majordome/tasks.py
@@ -18,7 +18,7 @@ log = L.setupLogger("MajordomeTaskLogger", "Majordome")
'''
Task to handle the execution of the program
- check the environment status in database (putted ther by the monitoring)
+ check the environment status in database
check the devices status (telescope / cameras)
check if the last schedule made has to be planned
launch schedule's sequences
@@ -51,8 +51,8 @@ class Majordome(Task):
'''
def run(self):
self.updateSoftware()
- self.setTime()
self.setContext()
+ self.setTime()
self.majordome_status = "EXECUTING"
self.loop()
@@ -101,20 +101,33 @@ class Majordome(Task):
if (self.night_start - 120 > getCurrentTime()):
self.timer_night_start = self.night_start - 120 - getCurrentTime()
self.timer_night_end = self.night_end - getCurrentTime()
+ if (getCurrentTime() > self.night_start):
+ self.adaptTimers()
self.timers = {
- "status": self.timer_status, "environment": self.timer_plc,
- "night_start": self.timer_night_start, "night_end": self.timer_night_end,
- "schedule": self.timer_schedule, "sequence" : self.timer_sequence
+ "status": self.timer_status,
+ "environment": self.timer_plc,
+ "night_start": self.timer_night_start,
+ "night_end": self.timer_night_end,
+ "schedule": self.timer_schedule,
+ "sequence": self.timer_sequence
+ }
+ self.functions = {
+ "status": self.handleStatusTimer,
+ "environment": self.handleEnvironmentTimer,
+ "night_start": self.handleNightStartTimer,
+ "night_end": self.handleNightEndTimer,
+ "schedule": self.handleScheduleTimer,
+ "sequence": self.handleSequenceTimer
}
-
- # TODO: utiliser un logiciel by AK pour stocker en local le début et la fin de la nuit (on est peut-être dedans)
return (0)
+ # TODO adapt timers when the majordome is started during the night
+ def adaptTimers(self):
+ pass
+
'''
Infinite loop according to the majordome behavior
-
- This function is a little fat (core of pyros) -> we maybe should cut it
'''
def loop(self):
while (self.majordome_status != "SHUTDOWN"):
@@ -124,43 +137,73 @@ class Majordome(Task):
self.timers = {key: value - self.timers[minimal_timer] for key, value in self.timers.items()}
for timer_name, timer_value in self.timers.items():
if (timer_value <= 0):
- if timer_name == "status":
- self.status_tel = self.tel.get("STATUS")
- self.status_nir = self.nir_camera.get("STATUS")
- self.status_vis = self.vis_camera.get("STATUS")
- self.handleStatus()
- self.timers["status"] = self.timer_status
- elif (timer_name == "environment"):
- site_status = SiteWatch.objects.latest('updated')
- weather_status = WeatherWatch.objects.latest('updated')
- self.handlePLC(site_status, weather_status)
- self.timers["environment"] = self.timer_plc
- if (self.isValidStatus(self.status_tel)):
- if (timer_name == "night_start"):
- scheduler.tasks.scheduling.delay(first_schedule=False, alert=False)
- self.timers["night_start"] = getNextNightStart()
- elif (timer_name == "night_end"):
- observation_manager.tasks.create_calibrations.delay()
- self.timers["night_end"] = getNextNightEnd()
- elif (timer_name == "schedule"):
- self.schedule = Schedule.objects.latest('created')
- shs_list = self.schedule.shs.filter(status=Sequence.PENDING).order_by('tsp')
- self.executeSchedule(shs_list)
- self.timers["scheduler"] = self.timer_schedule
- elif (timer_name == "sequence"):
- if (self.executing_sequence != None):
- self.handleSequence(self.executing_sequence[0],
- self.executing_sequence[1], self.executing_sequence[2])
- self.timers["sequence"] = self.timer_sequence
- else:
- log.info("Timer : " + str(timer_name) + "is not known by the Majordome")
- return (1)
+ if timer_name in self.functions:
+ self.functions[timer_name]()
else:
- self.notifyTelescopeStatus(timer_name)
+ if (settings.DEBUG):
+ log.info("Timer : " + str(timer_name) + "is not known by the Majordome")
if (settings.DEBUG):
log.info("Timer : " + str(timer_name) + " executed")
return (0)
+ def handleEnvironmentTimer(self):
+ self.timers["environment"] = self.timer_plc
+ site_status = SiteWatch.objects.latest('updated')
+ weather_status = WeatherWatch.objects.latest('updated')
+ self.handlePLC(site_status, weather_status)
+ return (0)
+
+ def handleStatusTimer(self):
+ self.timers["status"] = self.timer_status
+ self.status_tel = self.tel.get("STATUS")
+ self.status_nir = self.nir_camera.get("STATUS")
+ self.status_vis = self.vis_camera.get("STATUS")
+ self.handleStatus()
+ return (0)
+
+ def handleSequenceTimer(self):
+ self.timers["sequence"] = self.timer_sequence
+ if (self.isValidStatus(self.status_tel)):
+ if (self.executing_sequence != None):
+ self.handleSequence(self.executing_sequence[0],
+ self.executing_sequence[1], self.executing_sequence[2])
+ else:
+ self.notifyTelescopeStatus("sequence")
+ return (0)
+
+ def handleScheduleTimer(self):
+ self.timers["scheduler"] = self.timer_schedule
+ if (self.isValidStatus(self.status_tel)):
+ if (self.schedule == None):
+ self.schedule = Schedule.objects.latest('created')
+ else:
+ schedule = Schedule.objects.latest('created')
+ if (schedule.created != self.schedule.created):
+ self.next_sequence = None
+ self.schedule = schedule
+ if (self.schedule):
+ shs_list = self.schedule.shs.filter(status=Sequence.PENDING).order_by('tsp')
+ self.executeSchedule(shs_list)
+ else:
+ self.notifyTelescopeStatus("scheduler")
+ return (0)
+
+ def handleNightEndTimer(self):
+ self.timers["night_end"] = getNextNightEnd()
+ if (self.isValidStatus(self.status_tel)):
+ observation_manager.tasks.create_calibrations.delay()
+ else:
+ self.notifyTelescopeStatus("night_end")
+ return (0)
+
+ def handleNightStartTimer(self):
+ self.timers["night_start"] = getNextNightStart()
+ if (self.isValidStatus(self.status_tel)):
+ scheduler.tasks.scheduling.delay(first_schedule=False, alert=False)
+ else:
+ self.notifyTelescopeStatus("night_start")
+ return (0)
+
def notifyDeviceStatus(self, device_name, timer_name, status):
Log.objects.create(agent=device_name, create=datetime.datetime.now(),
message="The action : " + str(timer_name) + " has been canceled : Telescope status : "
@@ -174,15 +217,26 @@ class Majordome(Task):
def executeSchedule(self, shs_list):
for shs in shs_list: # shs_list is sorted by tsp
with shs.sequence as seq:
- if (seq.status == Sequence.OBSERVABLE):
+ if (seq.status == Sequence.OBSERVABLE and self.observable(seq)):
countdown = self.getCountdown(shs)
- if countdown <= JulianSeconds(5):
+ if countdown <= JulianSeconds(5) and countdown > 0:
if (self.executing_sequence == None):
self.executeSequence(shs, seq, countdown)
else:
self.setNextSequence(shs, seq, countdown)
+ else:
+ if (settings.DEBUG):
+ log.info("Sequence cannot be executed : countdown = " + str(countdown))
+ else:
+ if (settings.DEBUG):
+ log.info("Sequence cannot be executed : Not observable")
return (0)
+ def observable(self, sequence):
+ if (sequence.jd2 - sequence.duration - getCurrentTime() <= 0):
+ return (0)
+ return (1)
+
'''
Launch the observation tasks associated to a sequence
'''
@@ -233,8 +287,8 @@ class Majordome(Task):
self.executing_sequence = None
else:
self.executing_sequence = None
- self.executeSequence(self.executing_sequence[0],
- self.executing_sequence[1], self.executing_sequence[2])
+ self.executeSequence(self.next_sequence[0],
+ self.next_sequence[1], self.next_sequence[2])
self.next_sequence = None
return (0)
@@ -274,12 +328,16 @@ class Majordome(Task):
Function called to do an action with the devices status
'''
def handleStatus(self):
+ # TODO switch majordome state according to devices status
telescope = Telescope.objects.first()
camera_nir = Detector.objects.get(name="Cagire")
camera_vis = Detector.objects.get(name="Visible camera")
telescope.status = self.status_tel
camera_nir.status = self.status_nir
camera_vis.status = self.status_vis
+ telescope.save()
+ camera_nir.save()
+ camera_vis.save()
return (0)
'''
@@ -291,65 +349,34 @@ class Majordome(Task):
return (True)
'''
+ Put the system in Pause
+ '''
+ def systemPause(self, duration, cause: str):
+ time.sleep(duration)
+ scheduler.tasks.scheduling.delay(first_schedule=False, alert=False)
+ self.setTime()
+ print("system has been paused. Cause : " + cause)
+ return (0)
+
+ '''
Function called to do an action with the site status and the wheather status
'''
def handlePLC(self, site_status, weather_status):
return (0)
- """
+ '''
Gets the time before the expected start of the execution.
- """
+ '''
def getCountdown(self, shs):
# TODO start sequence as soon as possible (a lot of verifications must be done there)
current_time = secondsToJulianDate(getPreciseCurrentTime());
countdown = shs.tsp - current_time
return countdown
-'''
- Task called by the monitoring in case of problem.
- It stops the system and the instruments.
-'''
-class system_pause(Task):
- def run(self):
- time.sleep(5)
- print("system_pause")
-
-
-'''
- Task called by the monitoring when there is no more problem.
- Should just make a scheduling.
-'''
-class system_restart(Task):
-
- def run(self):
- time.sleep(5)
- print("system_restart")
-
+ '''
+ Change observation conditions
+ '''
+ def changeObsConditions(self):
-'''
- 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
-'''
-class change_obs_conditions(Task):
- def run(self):
- # important : penser à rendre les quotas aux users
- time.sleep(5)
print("change_obs_conditions")
-
-
-# Previouns code
-# --------------------------------------------------
-# 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")
-# -------------------------------------------------
+ pass
diff --git a/src/monitoring/tasks.py b/src/monitoring/tasks.py
index b3040e1..353e013 100644
--- a/src/monitoring/tasks.py
+++ b/src/monitoring/tasks.py
@@ -2,107 +2,51 @@ from __future__ import absolute_import
from django.conf import settings
from common.models import *
from celery.task import Task
-import scheduler.tasks
-import alert_manager.tasks
-import observation_manager.tasks
-import time
-
from devices.PLC import PLCController
-
-import time
-
-TIMER_CHECK = 10 # in seconds
+from utils.JDManipulator import *
+import utils.config as L
+log = L.setupLogger("MonitoringTaskLogger", "Monitoring")
'''
Infinite task created at the program's start.
- It initilize all the external connections, and starts the alert_listener.
-
- This is the place to put the starting configurations.
-
- Once the starting configurations are done, it becomes a loop that checks the PLC and instruments status.
- It also handles the beginning and the end of the night, recalculating them at each end of night.
+ Checks the plc status, parse it, analyse it, store it in db
'''
class monitoring(Task):
def run(self):
self.setContext()
- self.get_night_start_end()
-
- alert_manager.tasks.alert_listener.delay()
+ self.setTime()
+ self.loop()
- self.timers_loop()
-
- '''
- Creates the communication objects for each instrument, and give them the basic configurations.
- '''
def setContext(self):
self.plc = PLCController()
+ self.state = "RUNNING"
return (0)
- def timers_loop(self):
- '''
- Infinite loop for the different timers :
- - Every TIMER_CHECK seconds, check PLC and instruments status (+ analyse them and send them to the IC)
- - 2 minutes before the night start, make a scheduling
- - At the end of the night, do calibration files and computes the next night limits + make a scheduling with the new schedule
- '''
-
- timer_status = TIMER_CHECK
-
- ''' Set night start timer to 1 day, then compute the real ones if the current time isn't during the night '''
- timer_night_start = 86400
-
- night_start_seconds = self.night_start * 3600 * 24
- night_end_seconds = self.night_end * 3600 * 24
-
- if night_start_seconds - 120 > time.time():
- timer_night_start = night_start_seconds - 120 - time.time()
-
- timer_night_end = night_end_seconds - time.time()
-
- timers = {"status": timer_status, "night_start": timer_night_start, "night_end": timer_night_end}
-
- while True:
- minimal_timer = min(timers, key=timers.get)
- ''' Wait for the nearest timer '''
- time.sleep(timers[minimal_timer])
- ''' Update the timers '''
- timers = {key: value - timers[minimal_timer] for key, value in timers.items()}
-
- ''' Then check what timers are <= 0 '''
- for timer_name, timer_value in timers.items():
- if timer_value <= 0:
- if timer_name == "status":
-
- status_tel = self.tel.get("STATUS")
- status_nir = self.nir_camera.get("STATUS")
- status_vis = self.vis_camera.get("STATUS")
- status_plc = self.plc.get("STATUS")
-
- # TODO: stocker les statuts & les envoyer à l'IC
-
- timers["status"] = TIMER_CHECK
-
- self.analyze_plc_status()
-
- elif timer_name == "night_start":
- scheduler.tasks.scheduling.delay(first_schedule=False, alert=False)
- timers["night_start"] = 86400
- elif timer_name == "night_end":
- # TODO: faire un majordome.system_pause (fin de nuit)
- observation_manager.tasks.create_calibrations.delay()
- self.get_night_start_end()
- scheduler.tasks.scheduling(first_schedule=True, alert=False, night_start=self.night_start, night_end=self.night_end)
- timers["night_start"] = self.night_start * 3600 * 24 - time.time() - 120
- timers["night_end"] = self.night_end * 3600 * 24 - time.time()
+ def setTime(self):
+ self.timer_status = 10
+ self.timers = {"timer_status", self.timer_status}
+ self.functions = {"timer_status", self.handleTimerStatus}
+ return (0)
- def analyze_plc_status(self):
- '''
- Reads the status in DB, and fill missing fields (maybe ?)
- Determines the obs conditions and compare them with the previous ones to know if they changed
- Create a task to stop the system if there is a security problem
- '''
+ def handleTimerStatus(self):
+ self.timers["timer_status"] = self.timer_status
+ self.status_plc = self.plc.get("STATUS")
+ # TODO: parse, analyse, store
+ return (0)
- pass
- # TODO: toute la fct
- # On calcule le nouveau seeing, et si il y a eu du changement, on crée une tâche de majordome.change_obs_conditions
+ def loop(self):
+ while (self.state != "SHUTDOWN"):
+ minimal_timer = min(self.timers, key=self.timers.get)
+ time.sleep(self.timers[minimal_timer])
+ self.timers = {key: value - self.timers[minimal_timer] for key, value in self.timers.items()}
+ for timer_name, timer_value in self.timers.items():
+ if (timer_value <= 0):
+ if (timer_name in self.function):
+ self.functions[timer_name]()
+ else:
+ if (settings.DEBUG):
+ log.info("Timer : " + str(timer_name) + "is not known by the monitoring")
+ if (settings.DEBUG):
+ log.info("Timer : " + str(timer_name) + " executed by monitoring")
+ return (0)
\ No newline at end of file
--
libgit2 0.21.2