Blame view

src/majordome/tasks.py 22.1 KB
5b5566ab   haribo   added celery
1
from __future__ import absolute_import
ce470283   Jeremy   Plc simulator fin...
2

5b5566ab   haribo   added celery
3
from celery.task import Task
ce470283   Jeremy   Plc simulator fin...
4
5
6
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q

9774228b   haribo   Date: 22/06/2016
7
import observation_manager
abfb02e2   Jeremy   Device Model is n...
8
import observation_manager.tasks
ce470283   Jeremy   Plc simulator fin...
9
10
11
import scheduler
import scheduler.tasks as sched_task
import utils.Logger as L
c72eb17a   Jeremy   Update celery task
12
13
import monitoring.tasks
import alert_manager.tasks
ce470283   Jeremy   Plc simulator fin...
14
from common.models import *
65149de7   Jeremy   Update
15
from devices.CameraNIR import NIRCameraController
ce470283   Jeremy   Plc simulator fin...
16
from devices.CameraVIS import VISCameraController
cfc9d09c   Jeremy   Added dome simula...
17
from devices.Dome import DomeController
65149de7   Jeremy   Update
18
from devices.PLC import PLCController
ce470283   Jeremy   Plc simulator fin...
19
20
from devices.Telescope import TelescopeController
from majordome.MajordomeDecorators import *
65149de7   Jeremy   Update
21
from utils.JDManipulator import *
cfc9d09c   Jeremy   Added dome simula...
22

ff448d43   Jeremy   Update
23
DEBUG_FILE = False
65149de7   Jeremy   Update
24
log = L.setupLogger("MajordomeTaskLogger", "Majordome")
5b5566ab   haribo   added celery
25

65149de7   Jeremy   Update
26
'''
05038bc8   Jeremy   Majordome logic i...
27
    Task to handle the execution of the program
65149de7   Jeremy   Update
28

4cb0ff36   Jeremy   Update
29
    check the environment status in database
05038bc8   Jeremy   Majordome logic i...
30
31
32
    check the devices status (telescope / cameras)
    check if the last schedule made has to be planned
    launch schedule's sequences
65149de7   Jeremy   Update
33
34
35
36
'''
class Majordome(Task):
    loop_speed = 1
    julian_div = 86400
05038bc8   Jeremy   Majordome logic i...
37
38
39
40
41
    executing_sequence = None
    next_sequence = None
    status_tel = ""
    status_nir = ""
    status_vis = ""
cfc9d09c   Jeremy   Added dome simula...
42
    status_dom = ""
ce470283   Jeremy   Plc simulator fin...
43
44
    site_status = "OK"
    weather_status = "OK"
ef60c3ec   Jeremy   Majordome and mon...
45
46
47
    timers = {}
    functions = {}
    schedule = None
c53a13e0   Jeremy   Updating a lot of...
48
    available_status = []
ce470283   Jeremy   Plc simulator fin...
49
    current_status = "RUNNING"
678838ed   Jeremy   Weather ans insid...
50
    alarm_list = []
65149de7   Jeremy   Update
51

e8e6f017   Jeremy   Reworked devices ...
52
53
54
55
56
57
58
59
    '''
        Check if the instrument status is valid
    '''
    def isValidStatus(self, status):
        # TODO REMOVE COMMENT AND CHANGE WHEN DEFINED
        # if (status == "" or status == "ERROR" or status == "FAILED" or status == "NOT_SET"):
        #     return (False)
        return (True)
65149de7   Jeremy   Update
60
61
62
63
64
65

    def setContext(self):
        self.tel = TelescopeController()
        self.vis_camera = VISCameraController()
        self.nir_camera = NIRCameraController()
        self.plc = PLCController()
cfc9d09c   Jeremy   Added dome simula...
66
        self.dom = DomeController()
65149de7   Jeremy   Update
67
        return (0)
65149de7   Jeremy   Update
68

c72eb17a   Jeremy   Update celery task
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    def createTask(self):
        try:
            TaskId.objects.find(task="majordome").delete()
        except Exception as e:
            log.info(str(e))
            return 1
        TaskId.objects.create(task_id=self.request.id, task="majordome")
        return 0

    def setTasks(self):
        try:
            self.monitoring_task = TaskId.objects.get(task="monitoring")
            self.alert_task = TaskId.objects.get(task="alert_manager")
        except Exception as e:
            self.monitoring_task = None
            self.alert_task = None
        return 0

65149de7   Jeremy   Update
87
88
89
90
91
92
93
94
95
    '''
        Function called by celery task
        Behavior:
            Init telescope / cameras
            set night limits
            check the software version
            launch the majordome loop
    '''
    def run(self):
c72eb17a   Jeremy   Update celery task
96
        self.createTask()
65149de7   Jeremy   Update
97
        self.updateSoftware()
65149de7   Jeremy   Update
98
        self.setContext()
4cb0ff36   Jeremy   Update
99
        self.setTime()
c72eb17a   Jeremy   Update celery task
100
        self.setTasks()
65149de7   Jeremy   Update
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
        self.loop()

    '''
        Reads the softwares versions in the settings.py, store them in the DB and send them to the IC.
    '''
    def updateSoftware(self):
        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)
        return (0)

    '''
ce470283   Jeremy   Plc simulator fin...
117
        Loop to wait for the device to be idle with the starting configurations.
65149de7   Jeremy   Update
118
119
    '''
    def waitDevices(self):
ce470283   Jeremy   Plc simulator fin...
120
121
122
123
124
        while self.status_vis == "" and self.status_tel == "" and self.status_nir == "" and self.status_dom == "":
            self.status_vis = self.vis_camera.getStatus()
            self.status_nir = self.nir_camera.getStatus()
            self.status_tel = self.tel.getStatus()
            self.status_dom = self.dom.getStatus()
65149de7   Jeremy   Update
125
126
127
128
        return (0)

    '''
        Computes the beginning and the end of the following (or current) night
257abe9b   Jeremy   Added comments
129
        set the timers -> maybe put timers in a config file ?
65149de7   Jeremy   Update
130
131
132
133
134
135
    '''
    def setTime(self):
        self.night_start = getNightStart()
        self.night_end = getNightEnd()
        self.night_start_jd = secondsToJulianDate(getNightStart())
        self.night_end_jd = secondsToJulianDate(getNightEnd())
ef60c3ec   Jeremy   Majordome and mon...
136
137
        self.timer_night_start = self.night_start - getCurrentTime()
        self.timer_night_end = self.night_end - getCurrentTime()
65149de7   Jeremy   Update
138
        self.timer_status = 5
c72eb17a   Jeremy   Update celery task
139
        self.tasks_timer = 5
65149de7   Jeremy   Update
140
141
        self.timer_plc = 2
        self.timer_schedule = 1
05038bc8   Jeremy   Majordome logic i...
142
        self.timer_sequence = 1
65149de7   Jeremy   Update
143
144
145
146

        if (self.night_start - 120 > getCurrentTime()):
            self.timer_night_start = self.night_start - 120 - getCurrentTime()
        self.timer_night_end = self.night_end - getCurrentTime()
4cb0ff36   Jeremy   Update
147
148
        if (getCurrentTime() > self.night_start):
            self.adaptTimers()
65149de7   Jeremy   Update
149
150

        self.timers = {
4cb0ff36   Jeremy   Update
151
152
153
154
155
            "status": self.timer_status,
            "environment": self.timer_plc,
            "night_start": self.timer_night_start,
            "night_end": self.timer_night_end,
            "schedule": self.timer_schedule,
c72eb17a   Jeremy   Update celery task
156
157
            "sequence": self.timer_sequence,
            "tasks": self.tasks_timer
4cb0ff36   Jeremy   Update
158
        }
ff448d43   Jeremy   Update
159
        if (settings.DEBUG and DEBUG_FILE):
e8e6f017   Jeremy   Reworked devices ...
160
161
            log.info("Majordome started with timers : " + str(self.timers))
        # Functions called during the loop
4cb0ff36   Jeremy   Update
162
163
164
165
166
167
        self.functions = {
            "status": self.handleStatusTimer,
            "environment": self.handleEnvironmentTimer,
            "night_start": self.handleNightStartTimer,
            "night_end": self.handleNightEndTimer,
            "schedule": self.handleScheduleTimer,
c72eb17a   Jeremy   Update celery task
168
169
            "sequence": self.handleSequenceTimer,
            "tasks": self.handleTasks
65149de7   Jeremy   Update
170
        }
65149de7   Jeremy   Update
171
172
        return (0)

257abe9b   Jeremy   Added comments
173
174
175
    '''
        Function called by the main loop to handle the task event (check monitoring and alert_manager)
    '''
c72eb17a   Jeremy   Update celery task
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    def handleTasks(self):
        self.timers["tasks"] = self.tasks_timer
        if self.monitoring_task is None:
            try:
                self.monitoring_task = TaskId.objects.get(task="monitoring")
            except Exception as e:
                monitoring.tasks.Monitoring.apply_async()
                if settings.DEBUG and DEBUG_FILE:
                    log.info(str(e))
        if self.alert_task is None:
            try:
                self.alert_task = TaskId.objects.get(task="alert_manager")
            except Exception as e:
                alert_manager.tasks.AlertListener.apply_async()
                if settings.DEBUG and DEBUG_FILE:
                    log.info(str(e))
        return 0

    # TODO adapt timers if the majordome is started during the night or not ?
4cb0ff36   Jeremy   Update
195
196
197
    def adaptTimers(self):
        pass

bca9a283   Jeremy   Reworked the sche...
198
199
200
    def logDB(self, message: str):
        Log.objects.create(agent="Majordome", message=message)

65149de7   Jeremy   Update
201
202
    '''
        Infinite loop according to the majordome behavior
65149de7   Jeremy   Update
203
204
    '''
    def loop(self):
c53a13e0   Jeremy   Updating a lot of...
205
        while (self.current_status != "SHUTDOWN"):
65149de7   Jeremy   Update
206
207
208
209
            minimal_timer = min(self.timers, key=self.timers.get)
            if (self.timers[minimal_timer] > 0):
                time.sleep(self.timers[minimal_timer])
                self.timers = {key: value - self.timers[minimal_timer] for key, value in self.timers.items()}
65149de7   Jeremy   Update
210
211
            for timer_name, timer_value in self.timers.items():
                if (timer_value <= 0):
4cb0ff36   Jeremy   Update
212
                    if timer_name in self.functions:
bca9a283   Jeremy   Reworked the sche...
213
                        self.logDB("Executing timer " + str(timer_name))
4cb0ff36   Jeremy   Update
214
                        self.functions[timer_name]()
65149de7   Jeremy   Update
215
                    else:
ff448d43   Jeremy   Update
216
                        if (settings.DEBUG and DEBUG_FILE):
4cb0ff36   Jeremy   Update
217
                            log.info("Timer : " + str(timer_name) + "is not known by the Majordome")
bca9a283   Jeremy   Reworked the sche...
218
                        self.logDB("Timer " + str(timer_name) + " unknown")
ff448d43   Jeremy   Update
219
                    if (settings.DEBUG and DEBUG_FILE):
e8e6f017   Jeremy   Reworked devices ...
220
                        log.info("Timer : " + str(timer_name) + " executed")
05038bc8   Jeremy   Majordome logic i...
221
222
        return (0)

257abe9b   Jeremy   Added comments
223
224
225
    '''
        Function called by the main loop to handle environment event (PLC info)
    '''
4cb0ff36   Jeremy   Update
226
227
    def handleEnvironmentTimer(self):
        self.timers["environment"] = self.timer_plc
ce470283   Jeremy   Plc simulator fin...
228
        self.handlePLC()
4cb0ff36   Jeremy   Update
229
230
        return (0)

257abe9b   Jeremy   Added comments
231
232
233
    '''
        Function called by the main loop to handle the devices status
    '''
4cb0ff36   Jeremy   Update
234
235
    def handleStatusTimer(self):
        self.timers["status"] = self.timer_status
ce470283   Jeremy   Plc simulator fin...
236
237
238
239
        self.status_tel = self.tel.getStatus()
        self.status_nir = self.nir_camera.getStatus()
        self.status_vis = self.vis_camera.getStatus()
        self.status_dom = self.dom.getStatus()
4cb0ff36   Jeremy   Update
240
        self.handleStatus()
c72eb17a   Jeremy   Update celery task
241
        return 0
4cb0ff36   Jeremy   Update
242

257abe9b   Jeremy   Added comments
243
244
245
    '''
        Function called by the main loop to check if the executing sequence is finished
    '''
4cb0ff36   Jeremy   Update
246
247
    def handleSequenceTimer(self):
        self.timers["sequence"] = self.timer_sequence
ff448d43   Jeremy   Update
248
249
250
        if (self.executing_sequence):
            self.handleSequence(self.executing_sequence[0],
                                self.executing_sequence[1], self.executing_sequence[2])
4cb0ff36   Jeremy   Update
251
252
        return (0)

257abe9b   Jeremy   Added comments
253
254
255
    '''
        Function called by the main loop to check if there is a new schedule and to execute its sequences
    '''
4cb0ff36   Jeremy   Update
256
    def handleScheduleTimer(self):
ef60c3ec   Jeremy   Majordome and mon...
257
        self.timers["schedule"] = self.timer_schedule
4cb0ff36   Jeremy   Update
258
        if (self.isValidStatus(self.status_tel)):
ff448d43   Jeremy   Update
259
            if (self.schedule is None):
ef60c3ec   Jeremy   Majordome and mon...
260
261
262
                try:
                    self.schedule = Schedule.objects.latest('created')
                except ObjectDoesNotExist:
ff448d43   Jeremy   Update
263
                    if (settings.DEBUG and DEBUG_FILE):
ef60c3ec   Jeremy   Majordome and mon...
264
265
                        log.info("No schedule found in database")
                    return (1)
4cb0ff36   Jeremy   Update
266
            else:
ef60c3ec   Jeremy   Majordome and mon...
267
268
269
                try:
                    schedule = Schedule.objects.latest('created')
                except ObjectDoesNotExist:
ff448d43   Jeremy   Update
270
                    if (settings.DEBUG and DEBUG_FILE):
ef60c3ec   Jeremy   Majordome and mon...
271
272
                        log.info("No schedule found in database")
                    return (1)
4cb0ff36   Jeremy   Update
273
274
275
276
                if (schedule.created != self.schedule.created):
                    self.next_sequence = None
                    self.schedule = schedule
            if (self.schedule):
c53a13e0   Jeremy   Updating a lot of...
277
278
                shs_list = self.schedule.shs.filter(Q(status=Sequence.PLANNED) |
                                                    Q(status=Sequence.PENDING)).order_by('tsp')
4cb0ff36   Jeremy   Update
279
280
281
282
283
                self.executeSchedule(shs_list)
        else:
            self.notifyTelescopeStatus("scheduler")
        return (0)

257abe9b   Jeremy   Added comments
284
285
286
    '''
        Function called by the main loop to handle the end of a night
    '''
4cb0ff36   Jeremy   Update
287
    def handleNightEndTimer(self):
ce470283   Jeremy   Plc simulator fin...
288
        self.timers["night_end"] = getNightEnd()
4cb0ff36   Jeremy   Update
289
        if (self.isValidStatus(self.status_tel)):
c72eb17a   Jeremy   Update celery task
290
            observation_manager.tasks.night_calibrations.apply_async()
4cb0ff36   Jeremy   Update
291
292
293
294
        else:
            self.notifyTelescopeStatus("night_end")
        return (0)

257abe9b   Jeremy   Added comments
295
296
297
    '''
        Function called by the main llop to handle the beginning of a night
    '''
4cb0ff36   Jeremy   Update
298
299
    def handleNightStartTimer(self):
        self.timers["night_start"] = getNextNightStart()
c72eb17a   Jeremy   Update celery task
300
301
302
303
        if self.isOutsideOk():
            self.dom.open()
            self.vis_camera.open_shutter()
            self.nir_camera.open_shutter()
ce470283   Jeremy   Plc simulator fin...
304
        scheduler.tasks.scheduling.apply_async((False, False))
4cb0ff36   Jeremy   Update
305
306
        return (0)

ef60c3ec   Jeremy   Majordome and mon...
307
308
309
    def notifyTelescopeStatus(self, timer_name):
        return (self.notifyDeviceStatus("telescope", timer_name, self.status_tel))

05038bc8   Jeremy   Majordome logic i...
310
    def notifyDeviceStatus(self, device_name, timer_name, status):
ef60c3ec   Jeremy   Majordome and mon...
311
312
        Log.objects.create(agent=device_name, created=datetime.datetime.now(),
                           message="The action : " + str(timer_name) + " has been canceled : Telescope status : " + str(status))
ce470283   Jeremy   Plc simulator fin...
313
        # TODO MAYBE reset some variables and do a scheduling
65149de7   Jeremy   Update
314
315
316
        return (0)

    '''
257abe9b   Jeremy   Added comments
317
        Execute a schedule
65149de7   Jeremy   Update
318
319
    '''
    def executeSchedule(self, shs_list):
c72eb17a   Jeremy   Update celery task
320
        for shs in shs_list:  # shs_list is sorted by tsp
c53a13e0   Jeremy   Updating a lot of...
321
322
323
            if (self.executableSequence(shs.sequence.status) and self.observable(shs.sequence)):
                if self.next_sequence is None:
                    self.setNextSequence(shs, shs.sequence)
678838ed   Jeremy   Weather ans insid...
324
                if self.isExecutable() and self.executing_sequence is None:
c53a13e0   Jeremy   Updating a lot of...
325
326
327
328
329
                    if self.isValidTimer(self.next_sequence[0]):
                        if self.executeSequence(self.next_sequence[0], self.next_sequence[1]) == -1:
                            return -1
                        if self.next_sequence[0] != shs and self.next_sequence[1] != shs.sequence:
                            self.setNextSequence(shs, shs.sequence)
ff448d43   Jeremy   Update
330
                        else:
c53a13e0   Jeremy   Updating a lot of...
331
                            self.next_sequence = None
ff448d43   Jeremy   Update
332
333
                    else:
                        return 0
bca9a283   Jeremy   Reworked the sche...
334
            else:
ff448d43   Jeremy   Update
335
                if (settings.DEBUG and DEBUG_FILE):
bca9a283   Jeremy   Reworked the sche...
336
                    log.info("Sequence cannot be executed : Not observable")
ff448d43   Jeremy   Update
337
338
                self.logDB("Sequence "+shs.sequence.name+" cannot be executed : Not observable")
        return 0
05038bc8   Jeremy   Majordome logic i...
339

4cb0ff36   Jeremy   Update
340
    def observable(self, sequence):
ff448d43   Jeremy   Update
341
342
343
        if (sequence.jd2 - sequence.duration - secondsToPreciseJulianDate(getPreciseCurrentTime()) <= 0):
            return 0
        return 1
4cb0ff36   Jeremy   Update
344

c53a13e0   Jeremy   Updating a lot of...
345
346
347
348
349
    def executableSequence(self, status):
        if status == Sequence.PLANNED or status == Sequence.PENDING:
            return 1
        return 0

257abe9b   Jeremy   Added comments
350
351
352
    '''
        Kill the executing sequence and set its state to cancelled
    '''
678838ed   Jeremy   Weather ans insid...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    @executingSequenceExist
    def killExecutingSequence(self):
        shs = self.executing_sequence[0]
        sequence = self.executing_sequence[1]
        executing_plans = self.executing_sequence[2]

        shs.status = Sequence.CANCELLED
        sequence.status = Sequence.CANCELLED
        shs.save()
        sequence.save()
        for rev in executing_plans:
            if (not rev.failed() and not rev.successful()):
                rev.revoke(terminate=True)
        self.executing_sequence = None
        return 0

    def reset(self, type):
        if type == "WEATHER":
            self.dom.open()
c72eb17a   Jeremy   Update celery task
372
            scheduler.tasks.scheduling.delay((False, False))
678838ed   Jeremy   Weather ans insid...
373
        elif type == "INSIDE":
c72eb17a   Jeremy   Update celery task
374
            scheduler.tasks.scheduling.delay((False, False))
678838ed   Jeremy   Weather ans insid...
375

257abe9b   Jeremy   Added comments
376
377
378
    '''
        Handle a new alarm (called by isInsideOk or isWeatherOk)
    '''
678838ed   Jeremy   Weather ans insid...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
    @SameAlarmCheck
    def handleAlarm(self, type, pos=-1):
        if type == "WEATHER":
            #TODO send email
            self.dom.close()
            self.killExecutingSequence()
            self.vis_camera.park()
            self.nir_camera.park()
        elif type == "INSIDE":
            #TODO send email
            self.killExecutingSequence()
            self.vis_camera.park()
            self.nir_camera.park()
        elif type == "ENDED":
            if len(self.alarm_list) > 0 and pos != -1:
                ended = self.alarm_list[pos]
                del self.alarm_list[pos]
                self.reset(ended)
            return 0
        else:
            return 1
        self.alarm_list.append(type)
        return 0

    '''
        for now weather_status and site_status contains something different than OK if the status is critical
        Later we may have other states to handle
    '''
ce470283   Jeremy   Plc simulator fin...
407
408
409
    def isOutsideOk(self) -> bool:
        self.handlePLC()
        if self.weather_status == "OK":
678838ed   Jeremy   Weather ans insid...
410
411
            if "WEATHER" in self.alarm_list:
                self.handleAlarm("ENDED", self.alarm_list.index("WEATHER"))
ce470283   Jeremy   Plc simulator fin...
412
            return True
678838ed   Jeremy   Weather ans insid...
413
        self.handleAlarm("WEATHER")
ce470283   Jeremy   Plc simulator fin...
414
415
        return False

257abe9b   Jeremy   Added comments
416
417
418
    '''
        Check the telescope inside status
    '''
ce470283   Jeremy   Plc simulator fin...
419
420
421
    def isInsideOk(self) -> bool:
        self.handlePLC()
        if self.site_status == "OK":
678838ed   Jeremy   Weather ans insid...
422
423
            if "INSIDE" in self.alarm_list:
                self.handleAlarm("ENDED", self.alarm_list.index("INSIDE"))
ce470283   Jeremy   Plc simulator fin...
424
            return True
678838ed   Jeremy   Weather ans insid...
425
        self.handleAlarm("INSIDE")
ce470283   Jeremy   Plc simulator fin...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
        return False

    def isDevicesOk(self) -> bool:
        if self.isValidStatus(self.status_tel) and self.isValidStatus(self.status_dom)\
            and self.isValidStatus(self.status_vis) and self.isValidStatus(self.status_nir):
            return True
        return False

    def isExecutable(self) -> bool:
        if self.isValidStatus(self.status_tel) and self.isValidStatus(self.status_dom)\
                and self.isOutsideOk() and self.isInsideOk():
            return True
        return False

257abe9b   Jeremy   Added comments
440
441
442
    '''
        check if the sequence timer is valid for execution, also check if there is a scheduling task running
    '''
ce470283   Jeremy   Plc simulator fin...
443
    def isValidTimer(self, shs) -> bool:
c53a13e0   Jeremy   Updating a lot of...
444
445
        current_countdown = self.getCountdown(shs)
        if (current_countdown <= JulianSeconds(5)):
c53a13e0   Jeremy   Updating a lot of...
446
447
448
            try:
                task = TaskId.objects.filter(task="scheduling")
                if not task:
ce470283   Jeremy   Plc simulator fin...
449
450
                    return True
                return False
c53a13e0   Jeremy   Updating a lot of...
451
            except:
ce470283   Jeremy   Plc simulator fin...
452
453
                return True
        return False
c53a13e0   Jeremy   Updating a lot of...
454

05038bc8   Jeremy   Majordome logic i...
455
    '''
257abe9b   Jeremy   Added comments
456
        Launch the observation tasks NIR and VIS associated to a sequence
05038bc8   Jeremy   Majordome logic i...
457
    '''
c53a13e0   Jeremy   Updating a lot of...
458
    def executeSequence(self, shs, sequence):
3224f14a   Jeremy   Fixed some simula...
459
460
461
462
        shs.status = Sequence.EXECUTING
        sequence.status = Sequence.EXECUTING
        shs.save()
        sequence.save()
c53a13e0   Jeremy   Updating a lot of...
463
        log.info("Executing sequence id = " + str(sequence.pk))
bca9a283   Jeremy   Reworked the sche...
464
        self.logDB("Executing sequence")
05038bc8   Jeremy   Majordome logic i...
465
        plans_results = []
05038bc8   Jeremy   Majordome logic i...
466
467
468
        if sequence.albums.filter(detector__name="Cagire").exists():
            if (self.isValidStatus(self.status_nir)):
                for plan in sequence.albums.get(detector__name="Cagire").plans.all():
c53a13e0   Jeremy   Updating a lot of...
469
470
471
472
                    res = observation_manager.tasks.execute_plan_nir.apply_async(
                        (plan.id, float(self.getCountdown(shs))))
                    # JB TODO : is it still usefull ?
                    # TaskId.objects.create(task_id=res.id, task="execute_plan")
05038bc8   Jeremy   Majordome logic i...
473
                    plans_results.append(res)
ff448d43   Jeremy   Update
474
475
            else:
                self.notifyDeviceStatus("Cagire", "Sequence execution", self.status_nir)
c53a13e0   Jeremy   Updating a lot of...
476
477
478
                sequence.status = Sequence.CANCELLED
                shs.status = Sequence.CANCELLED
                shs.save()
ff448d43   Jeremy   Update
479
480
                sequence.save()
                return (1)
05038bc8   Jeremy   Majordome logic i...
481
482
483
        if sequence.albums.filter(detector__name="Visible camera").exists():
            if (self.isValidStatus(self.status_vis)):
                for plan in sequence.albums.get(detector__name="Visible camera").plans.all():
c53a13e0   Jeremy   Updating a lot of...
484
485
                    res = observation_manager.tasks.execute_plan_vis.apply_async(
                        (plan.id, float(self.getCountdown(shs))))
05038bc8   Jeremy   Majordome logic i...
486
487
488
                    plans_results.append(res)
            else:
                self.notifyDeviceStatus("Camera visible", "Sequence execution", self.status_vis)
c53a13e0   Jeremy   Updating a lot of...
489
490
491
                sequence.status = Sequence.CANCELLED
                shs.status = Sequence.CANCELLED
                shs.save()
05038bc8   Jeremy   Majordome logic i...
492
493
                sequence.save()
                return (1)
05038bc8   Jeremy   Majordome logic i...
494
        self.executing_sequence = [shs, sequence, plans_results]
05038bc8   Jeremy   Majordome logic i...
495
496
497
498
499
        return (0)

    '''
        Set the next sequence
    '''
c53a13e0   Jeremy   Updating a lot of...
500
    def setNextSequence(self, shs, sequence):
ff448d43   Jeremy   Update
501
        sequence.status = Sequence.PENDING
c53a13e0   Jeremy   Updating a lot of...
502
503
        shs.status = Sequence.PENDING
        self.next_sequence = [shs, sequence]
ff448d43   Jeremy   Update
504
        sequence.save()
c53a13e0   Jeremy   Updating a lot of...
505
        shs.save()
05038bc8   Jeremy   Majordome logic i...
506
507
508
509
510
511
        return (0)

    '''
        Check if the current sequence is finished
    '''
    def handleSequence(self, shs, sequence, executing_plans):
c53a13e0   Jeremy   Updating a lot of...
512
        count = 0
c53a13e0   Jeremy   Updating a lot of...
513
        for res in executing_plans:
05038bc8   Jeremy   Majordome logic i...
514
            try:
c53a13e0   Jeremy   Updating a lot of...
515
516
                if res.successful() or res.failed():
                    count += 1
05038bc8   Jeremy   Majordome logic i...
517
            except Exception as e:
678838ed   Jeremy   Weather ans insid...
518
519
                if DEBUG_FILE and settings.DEBUG:
                    log.info(str(e))
05038bc8   Jeremy   Majordome logic i...
520
521
522
523
524
                shs.status = Sequence.CANCELLED
                sequence.status = Sequence.CANCELLED
                shs.save()
                sequence.save()
                for rev in executing_plans:
c53a13e0   Jeremy   Updating a lot of...
525
526
527
                    if (not rev.failed() and not rev.successful()):
                        rev.revoke(terminate=True)
                self.executing_sequence = None
05038bc8   Jeremy   Majordome logic i...
528
                return (-1)
c53a13e0   Jeremy   Updating a lot of...
529
        if count >= len(executing_plans):
05038bc8   Jeremy   Majordome logic i...
530
531
532
533
534
            sequence.status = Sequence.EXECUTED
            shs.status = Sequence.EXECUTED
            sequence.save()
            shs.save()
            message = "Finished sequence " + str(sequence.pk) + " execution"
05038bc8   Jeremy   Majordome logic i...
535
            Log.objects.create(agent="Majordome", message=message)
c53a13e0   Jeremy   Updating a lot of...
536
            self.executing_sequence = None
05038bc8   Jeremy   Majordome logic i...
537
        return (0)
65149de7   Jeremy   Update
538
539
540
541

    '''
        Function called to do an action with the devices status
    '''
05038bc8   Jeremy   Majordome logic i...
542
    def handleStatus(self):
05038bc8   Jeremy   Majordome logic i...
543
544
545
        telescope = Telescope.objects.first()
        camera_nir = Detector.objects.get(name="Cagire")
        camera_vis = Detector.objects.get(name="Visible camera")
ce470283   Jeremy   Plc simulator fin...
546
547
548
        dome = Dome.objects.get(name="Dome")

        dome.status = self.status_dom
05038bc8   Jeremy   Majordome logic i...
549
550
551
        telescope.status = self.status_tel
        camera_nir.status = self.status_nir
        camera_vis.status = self.status_vis
ce470283   Jeremy   Plc simulator fin...
552
553
554
555
556

        dome.save()
        telescope.save()
        camera_nir.save()
        camera_vis.save()
bca9a283   Jeremy   Reworked the sche...
557
558
        self.logDB("Instrument status : dome  = " + str(self.status_dom) + ", telescope = " + str(self.status_tel)
                   + ", camera_nir = " + str(self.status_nir) + ", camera_vis" + str(self.status_vis))
65149de7   Jeremy   Update
559
560
561
        return (0)

    '''
3224f14a   Jeremy   Fixed some simula...
562
        Put the majordome in pause
4cb0ff36   Jeremy   Update
563
    '''
4cb0ff36   Jeremy   Update
564
    def systemPause(self, duration, cause: str):
bca9a283   Jeremy   Reworked the sche...
565
        self.logDB("System in pause for " + str(duration))
4cb0ff36   Jeremy   Update
566
        time.sleep(duration)
c72eb17a   Jeremy   Update celery task
567
        scheduler.tasks.scheduling.apply_async(first_schedule=False, alert=False)
4cb0ff36   Jeremy   Update
568
569
570
571
572
        self.setTime()
        print("system has been paused. Cause : " + cause)
        return (0)

    '''
65149de7   Jeremy   Update
573
574
        Function called to do an action with the site status and the wheather status
    '''
ce470283   Jeremy   Plc simulator fin...
575
576
577
578
579
580
581
582
583
584
585
    def handlePLC(self):
        try:
            site_status = SiteWatch.objects.latest('updated')
            weather_status = WeatherWatch.objects.latest('updated')
            self.weather_status = weather_status.global_status
            self.site_status = site_status.global_status
        except ObjectDoesNotExist as e:
            if (settings.DEBUG and DEBUG_FILE):
                log.info("No site_status or weather_status found in database : " + str(e))
            # TODO shutdown everything
            return 1
3224f14a   Jeremy   Fixed some simula...
586
        return 0
5b5566ab   haribo   added celery
587

4cb0ff36   Jeremy   Update
588
    '''
05038bc8   Jeremy   Majordome logic i...
589
        Gets the time before the expected start of the execution.
4cb0ff36   Jeremy   Update
590
    '''
05038bc8   Jeremy   Majordome logic i...
591
592
    def getCountdown(self, shs):
        # TODO start sequence as soon as possible (a lot of verifications must be done there)
ff448d43   Jeremy   Update
593
        current_time = secondsToPreciseJulianDate(getPreciseCurrentTime())
05038bc8   Jeremy   Majordome logic i...
594
        countdown = shs.tsp - current_time
9774228b   haribo   Date: 22/06/2016
595
        return countdown
7a79e25b   haribo   Date: 19/05/2016
596

4cb0ff36   Jeremy   Update
597
598
599
600
    '''
        Change observation conditions
    '''
    def changeObsConditions(self):
5b5566ab   haribo   added celery
601
        print("change_obs_conditions")
4cb0ff36   Jeremy   Update
602
        pass