From 4cb0ff365c316111b1d78d6a2765d460d40a4ece Mon Sep 17 00:00:00 2001 From: Jeremy Date: Thu, 5 Jan 2017 16:47:57 +0100 Subject: [PATCH] Update --- .idea/PYROS.iml | 48 ------------------------------------------------ .idea/dataSources.local.xml | 10 ---------- .idea/dataSources.xml | 13 ------------- .idea/inspectionProfiles/profiles_settings.xml | 9 --------- .idea/misc.xml | 7 ------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ .idea/workspace.xml | 1580 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/majordome/tasks.py | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------- src/monitoring/tasks.py | 120 ++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------------- 10 files changed, 152 insertions(+), 1862 deletions(-) delete mode 100644 .idea/PYROS.iml delete mode 100644 .idea/dataSources.local.xml delete mode 100644 .idea/dataSources.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml diff --git a/.idea/PYROS.iml b/.idea/PYROS.iml deleted file mode 100644 index 426641c..0000000 --- a/.idea/PYROS.iml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml deleted file mode 100644 index a1923d2..0000000 --- a/.idea/dataSources.local.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - false - true - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index 1c73c55..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - sqlite.xerial - true - true - $PROJECT_DIR$/src/pyros/settings.py - org.sqlite.JDBC - jdbc:sqlite:$PROJECT_DIR$/src/db.sqlite3 - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 17b6b9a..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 3d3cbc6..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 98b5922..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 389a79a..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,1580 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "device": 4 - "device": 5 - "device": 6 - "device": 7 - "device": 8 - Filter - Telesc - tasks - Device - device - Alert - alert - Requ - Request - AUTH_USER - Read in DB - user - PyrosUser - import - User - .pyros_user - RequestSer - getDefault - getNextDe - majordo - majordome.tas - save - get_ni - environe - Sequence - - - - - - - - - - - true - DEFINITION_ORDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - project - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1480600682550 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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