tasks.py
6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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.Telescope import TelescopeController
from devices.CameraVIS import VISCameraController
from devices.CameraNIR import NIRCameraController
from devices.PLC import PLCController
import time
TIMER_CHECK = 10 # in seconds
class monitoring(Task):
'''
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.
'''
def run(self):
print("monitoring")
self.configure_instruments()
self.update_software_versions()
self.get_night_start_end()
self.wait_devices_ready()
# TODO: décommenter pour lancer un scheduling
# scheduler.tasks.scheduling(first_schedule=True, alert=False, night_start=self.night_start, night_end=self.night_end)
alert_manager.tasks.alert_listener.delay()
self.timers_loop()
def configure_instruments(self):
'''
Creates the communication objects for each instrument, and give them the basic configurations.
'''
self.tel = TelescopeController()
self.vis_camera = VISCameraController()
self.nir_camera = NIRCameraController()
self.plc = PLCController()
self.vis_camera.do("COOLER", 1.0, -150.0)
self.nir_camera.do("COOLER", 1.0, -150.0)
self.tel.do("HOMING")
self.tel.do("DOORS", True)
# TODO: dire au plc d'ouvrir le dome
def update_software_versions(self):
'''
Reads the softwares versions in the settings.py, store them in the DB and send them to the IC.
'''
versions = settings.MODULES_VERSIONS
for module, version in versions.items():
same_module_versions = Version.objects.filter(module_name=module)
if same_module_versions.count() == 0:
Version.objects.create(module_name=module, version=version)
elif same_module_versions.order_by("-created")[0].version != version:
Version.objects.create(module_name=module, version=version)
# TODO: envoyer les versions à l'IC
def get_night_start_end(self):
'''
Computes the beginning and the end of the following (or current) night
'''
# TODO: utiliser un logiciel by AK pour stocker en local le début et la fin de la nuit (on est peut-être dedans)
self.night_start = time.time() + 180 / 86400
self.night_end = time.time() + 360 / 86400
pass
def wait_devices_ready(self):
'''
Loop to wait for the device to be idle avec the starting configurations.
'''
nir_st = ""
vis_st = ""
tel_st = ""
while nir_st != "IDLE" or vis_st != "IDLE" and tel_st != "IDLE":
nir_st = self.nir_camera.get("STATUS")
vis_st = self.vis_camera.get("STATUS")
tel_st = self.tel.get("STATUS")
# TODO: rajouter le fait que le dome doit être ouvert (PLC)
print("Devices ready !")
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 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
'''
pass
# TODO: toute la fct