Commit ff448d4329b07d1ced978bc76f93bcff8b1cc995

Authored by Jeremy
1 parent 675fb3d5
Exists in master and in 1 other branch dev

Update

logs/2 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +test
@@ -363,6 +363,18 @@ class Pyros(AManager): @@ -363,6 +363,18 @@ class Pyros(AManager):
363 help_message = "python neo.py" 363 help_message = "python neo.py"
364 init_fixture = "initial_fixture.json" 364 init_fixture = "initial_fixture.json"
365 365
  366 + def signal_handler(self, signal, frame):
  367 + self.printFullTerm(Colors.WARNING, "Ctrl-c catched")
  368 + for p in self.subproc:
  369 + proc, name = p
  370 + self.printColor(Colors.BLUE, "Killing process " + str(name))
  371 + proc.kill()
  372 + if self.current_command == "simulator" or self.current_command == "simulator_development":
  373 + self.changeDirectory(self.path_dir_file)
  374 + self.kill_simulation()
  375 + self.printFullTerm(Colors.WARNING, "Exiting")
  376 + sys.exit(0)
  377 +
366 def install(self): 378 def install(self):
367 if (self.system == "Windows"): 379 if (self.system == "Windows"):
368 self.execProcess("python install/install.py install") 380 self.execProcess("python install/install.py install")
@@ -496,6 +508,7 @@ class Pyros(AManager): @@ -496,6 +508,7 @@ class Pyros(AManager):
496 def simulator_development(self): 508 def simulator_development(self):
497 self.changeDirectory("src") 509 self.changeDirectory("src")
498 self.replacePatternInFile("CELERY_TEST = False", "CELERY_TEST = True", "pyros/settings.py") 510 self.replacePatternInFile("CELERY_TEST = False", "CELERY_TEST = True", "pyros/settings.py")
  511 + self.replacePatternInFile("SIMULATOR = False", "SIMULATOR = True", "pyros/settings.py")
499 self.execProcess("rm -f testdb.sqlite3") 512 self.execProcess("rm -f testdb.sqlite3")
500 self.changeDirectory("..") 513 self.changeDirectory("..")
501 self.migrate() 514 self.migrate()
@@ -535,6 +548,7 @@ class Pyros(AManager): @@ -535,6 +548,7 @@ class Pyros(AManager):
535 def simulator(self): 548 def simulator(self):
536 self.changeDirectory("src") 549 self.changeDirectory("src")
537 self.replacePatternInFile("CELERY_TEST = False", "CELERY_TEST = True", "pyros/settings.py") 550 self.replacePatternInFile("CELERY_TEST = False", "CELERY_TEST = True", "pyros/settings.py")
  551 + self.replacePatternInFile("SIMULATOR = False", "SIMULATOR = True", "pyros/settings.py")
538 self.execProcess("rm -f testdb.sqlite3") 552 self.execProcess("rm -f testdb.sqlite3")
539 self.changeDirectory("..") 553 self.changeDirectory("..")
540 self.migrate() 554 self.migrate()
@@ -569,6 +583,7 @@ class Pyros(AManager): @@ -569,6 +583,7 @@ class Pyros(AManager):
569 def kill_simulation(self): 583 def kill_simulation(self):
570 self.changeDirectory("src") 584 self.changeDirectory("src")
571 self.replacePatternInFile("CELERY_TEST = True", "CELERY_TEST = False", "pyros/settings.py") 585 self.replacePatternInFile("CELERY_TEST = True", "CELERY_TEST = False", "pyros/settings.py")
  586 + self.replacePatternInFile("SIMULATOR = True", "SIMULATOR = False", "pyros/settings.py")
572 if (self.system == "Windows"): 587 if (self.system == "Windows"):
573 self.execProcessAsync("taskkill /f /im python.exe") 588 self.execProcessAsync("taskkill /f /im python.exe")
574 self.execProcessAsync("rm -f testdb.sqlite3") 589 self.execProcessAsync("rm -f testdb.sqlite3")
@@ -638,7 +653,7 @@ class Pyros(AManager): @@ -638,7 +653,7 @@ class Pyros(AManager):
638 "update": self.update, 653 "update": self.update,
639 "server": self.server, 654 "server": self.server,
640 "clean": self.clean, 655 "clean": self.clean,
641 - "simulator_scheduler": self.simulator_development, 656 + "simulator_development": self.simulator_development,
642 "clean_logs": self.clean_logs, 657 "clean_logs": self.clean_logs,
643 "test": self.test, 658 "test": self.test,
644 "migrate": self.migrate, 659 "migrate": self.migrate,
@@ -677,7 +692,7 @@ class Pyros(AManager): @@ -677,7 +692,7 @@ class Pyros(AManager):
677 "start": "Stop the celery workers then the web server", 692 "start": "Stop the celery workers then the web server",
678 "stop": "stops the celery workers", 693 "stop": "stops the celery workers",
679 "simulator": "Launch a simulation", 694 "simulator": "Launch a simulation",
680 - "simulator_scheduler": "Simulation for the scheduler only", 695 + "simulator_development": "Simulation for the scheduler only",
681 "kill_simulation": "kill the simulators / celery workers / web server", 696 "kill_simulation": "kill the simulators / celery workers / web server",
682 "sims_launch": "Launch only the simulators", 697 "sims_launch": "Launch only the simulators",
683 } 698 }
simulators/config/conf.json
@@ -40,6 +40,10 @@ @@ -40,6 +40,10 @@
40 "userSimulator" : "routine_request_10.xml" 40 "userSimulator" : "routine_request_10.xml"
41 }, 41 },
42 { 42 {
  43 + "time" : 200,
  44 + "userSimulator" : "rou"
  45 + },
  46 + {
43 "time" : 35, 47 "time" : 35,
44 "plcSimulator" : {"rain" : 5, "cloud" : 3} 48 "plcSimulator" : {"rain" : 5, "cloud" : 3}
45 }, 49 },
@@ -62,5 +66,9 @@ @@ -62,5 +66,9 @@
62 { 66 {
63 "time" : 42, 67 "time" : 42,
64 "telescopeSimulator" : {"status" : "ERROR"} 68 "telescopeSimulator" : {"status" : "ERROR"}
  69 + },
  70 + {
  71 + "time" : 200,
  72 + "telescopeSimulator" : {"status" : "OFF"}
65 } 73 }
66 ] 74 ]
simulators/resources/routine_request_01.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="200" jd1="6000" jd2="18000" name="Sequence1 (200secs)" target_coords="10"> 3 + <sequence duration="200" jd1="15" jd2="60000" name="Sequence1 (200secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_02.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="100" jd1="6000" jd2="18000" name="Sequence2 (100 secs)" target_coords="10"> 3 + <sequence duration="100" jd1="60" jd2="60000" name="Sequence2 (100 secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="100" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="100" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_03.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="40" jd1="10000" jd2="15000" name="Sequence3 (40secs)" target_coords="10"> 3 + <sequence duration="40" jd1="60" jd2="60000" name="Sequence3 (40secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="40" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="40" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_04.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="500" jd1="12000" jd2="25000" name="Sequence 4 (500secs)" target_coords="10"> 3 + <sequence duration="500" jd1="12000" jd2="60000" name="Sequence 4 (500secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="500" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="500" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_05.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="10" jd1="6000" jd2="22000" name="Sequence5 (10secs)" target_coords="10"> 3 + <sequence duration="10" jd1="60" jd2="60000" name="Sequence5 (10secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="10" filter="First infrared filter" name="plan vis" nb_images="1"/> 5 <plan duration="10" filter="First infrared filter" name="plan vis" nb_images="1"/>
6 </album> 6 </album>
simulators/resources/routine_request_06.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="200" jd1="6000" jd2="18000" name="Sequence6 (200 secs)" target_coords="10"> 3 + <sequence duration="200" jd1="6000" jd2="60000" name="Sequence6 (200 secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_07.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="200" jd1="6000" jd2="18000" name="Sequence7 (200secs)" target_coords="10"> 3 + <sequence duration="200" jd1="6000" jd2="60000" name="Sequence7 (200secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_08.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="200" jd1="6000" jd2="18000" name="Sequence8 (200secs)" target_coords="10"> 3 + <sequence duration="200" jd1="19000" jd2="60000" name="Sequence8 (200secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_09.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="200" jd1="6000" jd2="18000" name="Sequence9 (200secs)" target_coords="10"> 3 + <sequence duration="200" jd1="1000" jd2="60000" name="Sequence9 (200secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
simulators/resources/routine_request_10.xml
1 <?xml version="1.0" ?> 1 <?xml version="1.0" ?>
2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test"> 2 <request submitted="1" relative="1" name="RequestSimulator" scientific_program="GRB" target_type="test">
3 - <sequence duration="200" jd1="6000" jd2="18000" name="Sequence10 (200secs)" target_coords="10"> 3 + <sequence duration="200" jd1="200" jd2="60000" name="Sequence10 (200secs)" target_coords="10">
4 <album detector="Visible camera" name="alb"> 4 <album detector="Visible camera" name="alb">
5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/> 5 <plan duration="200" filter="First infrared filter" name="New plan" nb_images="5"/>
6 </album> 6 </album>
src/common/RequestBuilder.py
@@ -31,7 +31,7 @@ class RequestBuilder(): @@ -31,7 +31,7 @@ class RequestBuilder():
31 raise RuntimeError( 31 raise RuntimeError(
32 "start_new_request MUST be invoked before creating any sequence") 32 "start_new_request MUST be invoked before creating any sequence")
33 33
34 - sequence = Sequence(name=name, status=Sequence.OBSERVABLE, priority=priority, 34 + sequence = Sequence(name=name, status=Sequence.TOBEPLANNED, priority=priority,
35 jd1=jd1, jd2=jd2, t_prefered=t_prefered, duration=duration) 35 jd1=jd1, jd2=jd2, t_prefered=t_prefered, duration=duration)
36 self.sequences[self.sequence_id] = sequence 36 self.sequences[self.sequence_id] = sequence
37 self.sequence_id += 1 37 self.sequence_id += 1
src/common/models.py
@@ -367,20 +367,19 @@ class Sequence(models.Model): @@ -367,20 +367,19 @@ class Sequence(models.Model):
367 INCOMPLETE = "INCPL" 367 INCOMPLETE = "INCPL"
368 COMPLETE = "CPL" 368 COMPLETE = "CPL"
369 TOBEPLANNED = "TBP" 369 TOBEPLANNED = "TBP"
370 - OBSERVABLE = "OBS"  
371 - UNPLANNABLE = "UNPLN" 370 + PLANNED = "PLND"
372 PENDING = "PNDG" 371 PENDING = "PNDG"
373 - EXECUTED = "EXD"  
374 EXECUTING = "EXING" 372 EXECUTING = "EXING"
  373 + EXECUTED = "EXD"
375 REJECTED = "RJTD" 374 REJECTED = "RJTD"
376 - CANCELLED = "CNCLD"  
377 INVALID = "INVL" 375 INVALID = "INVL"
378 - DEVICE_ERROR = "DVER" 376 + CANCELLED = "CNCLD"
  377 + UNPLANNABLE = "UNPLN"
379 STATUS_CHOICES = ( 378 STATUS_CHOICES = (
380 (INCOMPLETE, "Incomplete"), 379 (INCOMPLETE, "Incomplete"),
381 (COMPLETE, "Complete"), 380 (COMPLETE, "Complete"),
382 (TOBEPLANNED, "To be planned"), 381 (TOBEPLANNED, "To be planned"),
383 - (OBSERVABLE, "Observable"), 382 + (PLANNED, "Planned"),
384 (UNPLANNABLE, "Unplannable"), 383 (UNPLANNABLE, "Unplannable"),
385 (PENDING, "Pending"), 384 (PENDING, "Pending"),
386 (EXECUTED, "Executed"), 385 (EXECUTED, "Executed"),
@@ -388,7 +387,6 @@ class Sequence(models.Model): @@ -388,7 +387,6 @@ class Sequence(models.Model):
388 (REJECTED, "Rejected"), 387 (REJECTED, "Rejected"),
389 (CANCELLED, "Cancelled"), 388 (CANCELLED, "Cancelled"),
390 (INVALID, "Invalid"), 389 (INVALID, "Invalid"),
391 - (DEVICE_ERROR, "Device error"),  
392 ) 390 )
393 391
394 request = models.ForeignKey( 392 request = models.ForeignKey(
src/majordome/tasks.py
@@ -16,6 +16,7 @@ from django.conf import settings @@ -16,6 +16,7 @@ from django.conf import settings
16 from utils.JDManipulator import * 16 from utils.JDManipulator import *
17 import utils.Logger as L 17 import utils.Logger as L
18 18
  19 +DEBUG_FILE = False
19 log = L.setupLogger("MajordomeTaskLogger", "Majordome") 20 log = L.setupLogger("MajordomeTaskLogger", "Majordome")
20 21
21 ''' 22 '''
@@ -127,7 +128,7 @@ class Majordome(Task): @@ -127,7 +128,7 @@ class Majordome(Task):
127 "schedule": self.timer_schedule, 128 "schedule": self.timer_schedule,
128 "sequence": self.timer_sequence 129 "sequence": self.timer_sequence
129 } 130 }
130 - if (settings.DEBUG): 131 + if (settings.DEBUG and DEBUG_FILE):
131 log.info("Majordome started with timers : " + str(self.timers)) 132 log.info("Majordome started with timers : " + str(self.timers))
132 # Functions called during the loop 133 # Functions called during the loop
133 self.functions = { 134 self.functions = {
@@ -162,10 +163,10 @@ class Majordome(Task): @@ -162,10 +163,10 @@ class Majordome(Task):
162 self.logDB("Executing timer " + str(timer_name)) 163 self.logDB("Executing timer " + str(timer_name))
163 self.functions[timer_name]() 164 self.functions[timer_name]()
164 else: 165 else:
165 - if (settings.DEBUG): 166 + if (settings.DEBUG and DEBUG_FILE):
166 log.info("Timer : " + str(timer_name) + "is not known by the Majordome") 167 log.info("Timer : " + str(timer_name) + "is not known by the Majordome")
167 self.logDB("Timer " + str(timer_name) + " unknown") 168 self.logDB("Timer " + str(timer_name) + " unknown")
168 - if (settings.DEBUG): 169 + if (settings.DEBUG and DEBUG_FILE):
169 log.info("Timer : " + str(timer_name) + " executed") 170 log.info("Timer : " + str(timer_name) + " executed")
170 return (0) 171 return (0)
171 172
@@ -175,7 +176,7 @@ class Majordome(Task): @@ -175,7 +176,7 @@ class Majordome(Task):
175 site_status = SiteWatch.objects.latest('updated') 176 site_status = SiteWatch.objects.latest('updated')
176 weather_status = WeatherWatch.objects.latest('updated') 177 weather_status = WeatherWatch.objects.latest('updated')
177 except ObjectDoesNotExist: 178 except ObjectDoesNotExist:
178 - if (settings.DEBUG): 179 + if (settings.DEBUG and DEBUG_FILE):
179 log.info("No site_status or weather_status found in database") 180 log.info("No site_status or weather_status found in database")
180 return (1) 181 return (1)
181 self.handlePLC(site_status, weather_status) 182 self.handlePLC(site_status, weather_status)
@@ -192,29 +193,26 @@ class Majordome(Task): @@ -192,29 +193,26 @@ class Majordome(Task):
192 193
193 def handleSequenceTimer(self): 194 def handleSequenceTimer(self):
194 self.timers["sequence"] = self.timer_sequence 195 self.timers["sequence"] = self.timer_sequence
195 - if (self.isValidStatus(self.status_tel)):  
196 - if (self.executing_sequence != None):  
197 - self.handleSequence(self.executing_sequence[0],  
198 - self.executing_sequence[1], self.executing_sequence[2])  
199 - else:  
200 - self.notifyTelescopeStatus("sequence") 196 + if (self.executing_sequence):
  197 + self.handleSequence(self.executing_sequence[0],
  198 + self.executing_sequence[1], self.executing_sequence[2])
201 return (0) 199 return (0)
202 200
203 def handleScheduleTimer(self): 201 def handleScheduleTimer(self):
204 self.timers["schedule"] = self.timer_schedule 202 self.timers["schedule"] = self.timer_schedule
205 if (self.isValidStatus(self.status_tel)): 203 if (self.isValidStatus(self.status_tel)):
206 - if (self.schedule == None): 204 + if (self.schedule is None):
207 try: 205 try:
208 self.schedule = Schedule.objects.latest('created') 206 self.schedule = Schedule.objects.latest('created')
209 except ObjectDoesNotExist: 207 except ObjectDoesNotExist:
210 - if (settings.DEBUG): 208 + if (settings.DEBUG and DEBUG_FILE):
211 log.info("No schedule found in database") 209 log.info("No schedule found in database")
212 return (1) 210 return (1)
213 else: 211 else:
214 try: 212 try:
215 schedule = Schedule.objects.latest('created') 213 schedule = Schedule.objects.latest('created')
216 except ObjectDoesNotExist: 214 except ObjectDoesNotExist:
217 - if (settings.DEBUG): 215 + if (settings.DEBUG and DEBUG_FILE):
218 log.info("No schedule found in database") 216 log.info("No schedule found in database")
219 return (1) 217 return (1)
220 if (schedule.created != self.schedule.created): 218 if (schedule.created != self.schedule.created):
@@ -256,52 +254,66 @@ class Majordome(Task): @@ -256,52 +254,66 @@ class Majordome(Task):
256 Function called when a schedule has to be executed 254 Function called when a schedule has to be executed
257 ''' 255 '''
258 def executeSchedule(self, shs_list): 256 def executeSchedule(self, shs_list):
  257 + is_prev_planned = False
259 self.logDB("Trying to execute a sequence from current schedule") 258 self.logDB("Trying to execute a sequence from current schedule")
260 for shs in shs_list: # shs_list is sorted by tsp 259 for shs in shs_list: # shs_list is sorted by tsp
261 - if (shs.sequence.status == Sequence.OBSERVABLE and self.observable(shs.sequence)): 260 + if (shs.sequence.status == Sequence.PLANNED and self.observable(shs.sequence)):
262 countdown = self.getCountdown(shs) 261 countdown = self.getCountdown(shs)
263 - if countdown <= JulianSeconds(5) and countdown > 0:  
264 - if (self.executing_sequence == None):  
265 - self.executeSequence(shs, shs.sequence, countdown)  
266 - else: 262 + # if (countdown <= 6):
  263 + # TODO CHECK IF OBSERVABLE ELSE RESCHEDULE
  264 + if countdown <= JulianSeconds(5):
  265 + if self.executing_sequence is None:
  266 + if self.switchSequence():
  267 + self.executeSequence(shs, shs.sequence, countdown)
  268 + else:
  269 + self.setNextSequence(shs, shs.sequence, countdown)
  270 + elif self.next_sequence is None:
267 self.setNextSequence(shs, shs.sequence, countdown) 271 self.setNextSequence(shs, shs.sequence, countdown)
268 - else:  
269 - if (settings.DEBUG):  
270 - log.info("Sequence cannot be executed : countdown = " + str(countdown))  
271 - self.logDB("Sequence cannot be executed : countdown = " + str(countdown)) 272 + else:
  273 + return 0
  274 + elif self.next_sequence is None:
  275 + self.setNextSequence(shs, shs.sequence, countdown)
272 else: 276 else:
273 - if (settings.DEBUG): 277 + if (settings.DEBUG and DEBUG_FILE):
274 log.info("Sequence cannot be executed : Not observable") 278 log.info("Sequence cannot be executed : Not observable")
275 - self.logDB("Sequence cannot be executed : Not observable")  
276 - return (0) 279 + self.logDB("Sequence "+shs.sequence.name+" cannot be executed : Not observable")
  280 + return 0
277 281
278 def observable(self, sequence): 282 def observable(self, sequence):
279 - if (sequence.jd2 - sequence.duration - getCurrentTime() <= 0):  
280 - return (0)  
281 - return (1) 283 + if (sequence.jd2 - sequence.duration - secondsToPreciseJulianDate(getPreciseCurrentTime()) <= 0):
  284 + return 0
  285 + return 1
282 286
283 ''' 287 '''
284 Launch the observation tasks associated to a sequence 288 Launch the observation tasks associated to a sequence
285 ''' 289 '''
286 def executeSequence(self, shs, sequence, countdown): 290 def executeSequence(self, shs, sequence, countdown):
  291 + if (countdown > JulianSeconds(5)):
  292 + if self.next_sequence and self.next_sequence[1].status == Sequence.PENDING:
  293 + self.next_sequence[1].status = Sequence.PLANNED
  294 + self.next_sequence[1].save()
  295 + return 0
  296 + if self.next_sequence and self.next_sequence[1].status == Sequence.PLANNED:
  297 + self.next_sequence[1].status = Sequence.PENDING
  298 + self.next_sequence[1].save()
  299 +
287 self.logDB("Executing sequence") 300 self.logDB("Executing sequence")
288 plans_results = [] 301 plans_results = []
289 -  
290 if sequence.albums.filter(detector__name="Cagire").exists(): 302 if sequence.albums.filter(detector__name="Cagire").exists():
291 if (self.isValidStatus(self.status_nir)): 303 if (self.isValidStatus(self.status_nir)):
292 for plan in sequence.albums.get(detector__name="Cagire").plans.all(): 304 for plan in sequence.albums.get(detector__name="Cagire").plans.all():
293 - res = observation_manager.tasks.execute_plan_nir.apply_async((plan.id, countdown)) 305 + res = observation_manager.tasks.execute_plan_nir.apply_async((plan.id, float(countdown)))
294 TaskId.objects.create(task_id=res.id, task="execute_plan") 306 TaskId.objects.create(task_id=res.id, task="execute_plan")
295 plans_results.append(res) 307 plans_results.append(res)
296 - else:  
297 - self.notifyDeviceStatus("Cagire", "Sequence execution", self.status_nir)  
298 - sequence.status = Sequence.DEVICE_ERROR  
299 - sequence.save()  
300 - return (1) 308 + else:
  309 + self.notifyDeviceStatus("Cagire", "Sequence execution", self.status_nir)
  310 + sequence.status = Sequence.DEVICE_ERROR
  311 + sequence.save()
  312 + return (1)
301 if sequence.albums.filter(detector__name="Visible camera").exists(): 313 if sequence.albums.filter(detector__name="Visible camera").exists():
302 if (self.isValidStatus(self.status_vis)): 314 if (self.isValidStatus(self.status_vis)):
303 for plan in sequence.albums.get(detector__name="Visible camera").plans.all(): 315 for plan in sequence.albums.get(detector__name="Visible camera").plans.all():
304 - res = observation_manager.tasks.execute_plan_vis.apply_async((plan.id, countdown)) 316 + res = observation_manager.tasks.execute_plan_vis.apply_async((plan.id, float(countdown)))
305 TaskId.objects.create(task_id=res.id, task="execute_plan") 317 TaskId.objects.create(task_id=res.id, task="execute_plan")
306 plans_results.append(res) 318 plans_results.append(res)
307 else: 319 else:
@@ -320,20 +332,22 @@ class Majordome(Task): @@ -320,20 +332,22 @@ class Majordome(Task):
320 Set the next sequence 332 Set the next sequence
321 ''' 333 '''
322 def setNextSequence(self, shs, sequence, countdown): 334 def setNextSequence(self, shs, sequence, countdown):
  335 + sequence.status = Sequence.PENDING
323 self.next_sequence = [shs, sequence, countdown] 336 self.next_sequence = [shs, sequence, countdown]
  337 + sequence.save()
324 return (0) 338 return (0)
325 339
326 ''' 340 '''
327 Switch sequences 341 Switch sequences
328 ''' 342 '''
329 def switchSequence(self): 343 def switchSequence(self):
330 - if (self.next_sequence == None):  
331 - self.executing_sequence = None  
332 - else:  
333 - self.executing_sequence = None 344 + self.executing_sequence = None
  345 + if (self.next_sequence is not None):
334 self.executeSequence(self.next_sequence[0], 346 self.executeSequence(self.next_sequence[0],
335 self.next_sequence[1], self.next_sequence[2]) 347 self.next_sequence[1], self.next_sequence[2])
336 self.next_sequence = None 348 self.next_sequence = None
  349 + else:
  350 + return 1
337 return (0) 351 return (0)
338 352
339 ''' 353 '''
@@ -414,7 +428,7 @@ class Majordome(Task): @@ -414,7 +428,7 @@ class Majordome(Task):
414 ''' 428 '''
415 def getCountdown(self, shs): 429 def getCountdown(self, shs):
416 # TODO start sequence as soon as possible (a lot of verifications must be done there) 430 # TODO start sequence as soon as possible (a lot of verifications must be done there)
417 - current_time = secondsToJulianDate(getPreciseCurrentTime()); 431 + current_time = secondsToPreciseJulianDate(getPreciseCurrentTime())
418 countdown = shs.tsp - current_time 432 countdown = shs.tsp - current_time
419 return countdown 433 return countdown
420 434
src/misc/static/media/next.png 0 → 100644

3.27 KB

src/misc/static/media/planned.png 0 → 100644

3.79 KB

src/observation_manager/tasks.py
@@ -6,6 +6,7 @@ from devices import CameraVIS as VIS @@ -6,6 +6,7 @@ from devices import CameraVIS as VIS
6 from devices import CameraNIR as NIR 6 from devices import CameraNIR as NIR
7 from devices import Telescope 7 from devices import Telescope
8 import time 8 import time
  9 +from utils.Logger import setupLogger
9 10
10 ''' 11 '''
11 Super class for execute_plan_vis / _nir 12 Super class for execute_plan_vis / _nir
@@ -13,6 +14,7 @@ import time @@ -13,6 +14,7 @@ import time
13 class execute_plan(Task): 14 class execute_plan(Task):
14 15
15 def run(self, plan_id, countdown, type): 16 def run(self, plan_id, countdown, type):
  17 +
16 if countdown > 0: 18 if countdown > 0:
17 time.sleep(countdown) 19 time.sleep(countdown)
18 TaskId.objects.filter(task_id=self.request.id).delete() 20 TaskId.objects.filter(task_id=self.request.id).delete()
@@ -102,7 +104,10 @@ class execute_plan(Task): @@ -102,7 +104,10 @@ class execute_plan(Task):
102 Send the images to the analyzer 104 Send the images to the analyzer
103 ''' 105 '''
104 class execute_plan_vis(execute_plan): 106 class execute_plan_vis(execute_plan):
  107 + logger = setupLogger("PlanVIS", "PlanVIS")
  108 +
105 def run(self, plan_id, countdown): 109 def run(self, plan_id, countdown):
  110 + self.log.info("------------------ RUNNING PLAN VIS ----------------------------")
106 super().run(plan_id, countdown, "VIS") 111 super().run(plan_id, countdown, "VIS")
107 112
108 113
@@ -111,8 +116,11 @@ class execute_plan_vis(execute_plan): @@ -111,8 +116,11 @@ class execute_plan_vis(execute_plan):
111 Send the images to the analyzer 116 Send the images to the analyzer
112 ''' 117 '''
113 class execute_plan_nir(execute_plan): 118 class execute_plan_nir(execute_plan):
  119 + log = setupLogger("PlanNIR", "PlanNIR")
  120 +
114 def run(self, plan_id, countdown): 121 def run(self, plan_id, countdown):
115 super().run(plan_id, countdown, "NIR") 122 super().run(plan_id, countdown, "NIR")
  123 + self.log.info("------------------ RUNNING PLAN NIR ----------------------------")
116 124
117 125
118 ''' 126 '''
@@ -120,6 +128,8 @@ class execute_plan_nir(execute_plan): @@ -120,6 +128,8 @@ class execute_plan_nir(execute_plan):
120 When they are all finished, it creates the 'super' calibration files. 128 When they are all finished, it creates the 'super' calibration files.
121 ''' 129 '''
122 class create_calibrations(Task): 130 class create_calibrations(Task):
123 - def run(self):  
124 - # TODO: attendre que tout soit idle  
125 - pass 131 + logger = setupLogger("Calibrations", "Calibrations")
  132 +
  133 + def run(self):
  134 + self.log.info("------------------ RUNNING CALIBRATIONS ----------------------------")
  135 + # TODO: attendre que tout soit idle
src/pyros/settings.py.bak
@@ -119,7 +119,9 @@ LOGIN_URL = &quot;/&quot; @@ -119,7 +119,9 @@ LOGIN_URL = &quot;/&quot;
119 119
120 # EP modif 120 # EP modif
121 121
122 -CELERY_TEST = True 122 +SIMULATOR = True
  123 +
  124 +CELERY_TEST = False
123 125
124 if not CELERY_TEST: 126 if not CELERY_TEST:
125 if not MYSQL: 127 if not MYSQL:
src/routine_manager/RequestSerializer.py
@@ -88,8 +88,6 @@ class RequestSerializer(): @@ -88,8 +88,6 @@ class RequestSerializer():
88 sequence.jd1 = (time.time() + float(sequence.jd1)) / 86400 + TIMESTAMP_JD 88 sequence.jd1 = (time.time() + float(sequence.jd1)) / 86400 + TIMESTAMP_JD
89 sequence.jd2 = (time.time() + float(sequence.jd2)) / 86400 + TIMESTAMP_JD 89 sequence.jd2 = (time.time() + float(sequence.jd2)) / 86400 + TIMESTAMP_JD
90 sequence.request = self.request 90 sequence.request = self.request
91 - # TODO: REMOVE WHEN WE KNOW HOW TO DECIDE IF THE SEQUENCE IS OBSERVABLE  
92 - sequence.status = Sequence.OBSERVABLE  
93 sequence.save() 91 sequence.save()
94 for album, plans in albums: 92 for album, plans in albums:
95 album.sequence = sequence 93 album.sequence = sequence
src/routine_manager/validators.py
1 from common.models import Sequence 1 from common.models import Sequence
  2 +from django.conf import settings
2 3
3 def check_plan_validity(plan): 4 def check_plan_validity(plan):
4 """ 5 """
@@ -52,7 +53,11 @@ def check_sequence_validity(seq): @@ -52,7 +53,11 @@ def check_sequence_validity(seq):
52 if seq.albums.filter(complete=False).count() != 0 or seq.albums.count() == 0: 53 if seq.albums.filter(complete=False).count() != 0 or seq.albums.count() == 0:
53 seq.status = Sequence.INCOMPLETE 54 seq.status = Sequence.INCOMPLETE
54 else: 55 else:
55 - seq.status = Sequence.COMPLETE 56 + #TODO CHANGE WHEN WE KNOW HOW TO DECIDE IF THE SEQUENCE IS OBSERVABLE
  57 + if settings.SIMULATOR:
  58 + seq.status = Sequence.TOBEPLANNED
  59 + else:
  60 + seq.status = Sequence.COMPLETE
56 seq.save() 61 seq.save()
57 return check_request_validity(seq.request) 62 return check_request_validity(seq.request)
58 63
src/routine_manager/views.py
@@ -428,7 +428,7 @@ def submit_request(request, req_id, redir): @@ -428,7 +428,7 @@ def submit_request(request, req_id, redir):
428 return redirect(action_request, req_id=req_id, action="view", status=-1, message=message) 428 return redirect(action_request, req_id=req_id, action="view", status=-1, message=message)
429 429
430 for seq in req.sequences.all(): 430 for seq in req.sequences.all():
431 - seq.status = Sequence.OBSERVABLE # TODO: utiliser le monitoring (regarder les conditions d'obseration pour dire si on met TBP ou OBS) 431 + seq.status = Sequence.TOBEPLANNED
432 seq.save() 432 seq.save()
433 req.submitted = True 433 req.submitted = True
434 req.save() 434 req.save()
@@ -460,7 +460,7 @@ def unsubmit_request(request, req_id): @@ -460,7 +460,7 @@ def unsubmit_request(request, req_id):
460 460
461 req.submitted = False 461 req.submitted = False
462 req.save() 462 req.save()
463 - sequences = req.sequences.filter(Q(status=Sequence.TOBEPLANNED) | Q(status=Sequence.OBSERVABLE) | 463 + sequences = req.sequences.filter(Q(status=Sequence.TOBEPLANNED) | Q(status=Sequence.PLANNED) |
464 Q(status=Sequence.INVALID) | Q(status=Sequence.UNPLANNABLE)) 464 Q(status=Sequence.INVALID) | Q(status=Sequence.UNPLANNABLE))
465 for seq in sequences: 465 for seq in sequences:
466 seq.status = Sequence.COMPLETE 466 seq.status = Sequence.COMPLETE
src/scheduler/Scheduler.py
1 from operator import attrgetter 1 from operator import attrgetter
2 from .UserManager import UserManager 2 from .UserManager import UserManager
3 from .Interval import * 3 from .Interval import *
  4 +from django.db.models import Q
4 5
5 SIMULATION = False 6 SIMULATION = False
6 - 7 +DEBUG_FILE = False
7 8
8 class Scheduler(IntervalManagement): 9 class Scheduler(IntervalManagement):
9 REJECTED_ROOM = "Insufficient room for this sequence" 10 REJECTED_ROOM = "Insufficient room for this sequence"
@@ -29,27 +30,43 @@ class Scheduler(IntervalManagement): @@ -29,27 +30,43 @@ class Scheduler(IntervalManagement):
29 def isFirstSchedule(self) -> bool: 30 def isFirstSchedule(self) -> bool:
30 return False 31 return False
31 32
  33 + def determinePlanStart(self, previous_sched):
  34 + start = secondsToPreciseJulianDate(getPreciseCurrentTime())
  35 + if start > previous_sched.plan_start + self.max_overhead:
  36 + return start + self.max_overhead
  37 + return previous_sched.plan_start
  38 +
32 def copyFromPrevious(self) -> int: 39 def copyFromPrevious(self) -> int:
33 if len(Schedule.objects.all()) == 1: 40 if len(Schedule.objects.all()) == 1:
34 self.schedule.plan_night_start = self.schedule.plan_start 41 self.schedule.plan_night_start = self.schedule.plan_start
35 - self.log("No schedule found") 42 + if DEBUG_FILE:
  43 + self.log("No schedule found")
36 return 1 44 return 1
37 try: 45 try:
38 previous_sched = Schedule.objects.order_by('-created')[1] 46 previous_sched = Schedule.objects.order_by('-created')[1]
39 - previous_exc_seq = previous_sched.sequences.filter(status=Sequence.EXECUTED) 47 + previous_exc_seq = previous_sched.sequences.filter(Q(status=Sequence.EXECUTED) |
  48 + Q(status=Sequence.EXECUTING))
40 except: 49 except:
41 self.schedule.plan_night_start = self.schedule.plan_start 50 self.schedule.plan_night_start = self.schedule.plan_start
42 - self.debug("Scheduler could not get information from previous schedule") 51 + if DEBUG_FILE:
  52 + self.debug("Scheduler could not get information from previous schedule")
43 return 1 53 return 1
44 for seq in previous_exc_seq: 54 for seq in previous_exc_seq:
45 - shs = seq.shs 55 + shs = seq.shs.latest("schedule__created")
46 shs.pk = None 56 shs.pk = None
47 shs.schedule = self.schedule 57 shs.schedule = self.schedule
48 shs.save() 58 shs.save()
  59 + adder = 0
  60 + try:
  61 + executing = Sequence.objects.filter(status=Sequence.EXECUTING)
  62 + if executing:
  63 + s = Sequence.shs.latest("schedule__created")
  64 + adder = s.tsp - secondsToPreciseJulianDate(getPreciseCurrentTime())
  65 + except:
  66 + pass
49 self.schedule.plan_night_start = previous_sched.plan_night_start 67 self.schedule.plan_night_start = previous_sched.plan_night_start
50 self.schedule.plan_end = previous_sched.plan_end 68 self.schedule.plan_end = previous_sched.plan_end
51 - start = Decimal(secondsToJulianDate(getCurrentTime())) + self.max_overhead  
52 - self.schedule.plan_start = (start if start > previous_sched.plan_start else previous_sched.plan_start) 69 + self.schedule.plan_start = self.determinePlanStart(previous_sched) + adder
53 return 0 70 return 0
54 71
55 def simulateSchedule(self, sequences) -> tuple: 72 def simulateSchedule(self, sequences) -> tuple:
@@ -68,7 +85,8 @@ class Scheduler(IntervalManagement): @@ -68,7 +85,8 @@ class Scheduler(IntervalManagement):
68 def computeSchedule(self) -> int: 85 def computeSchedule(self) -> int:
69 interval = Interval(self.schedule.plan_start, self.schedule.plan_end) 86 interval = Interval(self.schedule.plan_start, self.schedule.plan_end)
70 self.intervals.append(interval) 87 self.intervals.append(interval)
71 - self.log("Interval created : " + str(interval.__dict__)) 88 + if DEBUG_FILE:
  89 + self.log("Interval created : " + str(interval.__dict__))
72 self.removeInvalidSequences() 90 self.removeInvalidSequences()
73 self.determinePriorities() 91 self.determinePriorities()
74 self.removeNonEligible() 92 self.removeNonEligible()
@@ -86,21 +104,27 @@ class Scheduler(IntervalManagement): @@ -86,21 +104,27 @@ class Scheduler(IntervalManagement):
86 if self.copyFromPrevious(): 104 if self.copyFromPrevious():
87 self.schedule.plan_night_start = self.schedule.plan_start 105 self.schedule.plan_night_start = self.schedule.plan_start
88 106
89 - self.sequences = list(Sequence.objects.filter()) 107 + self.sequences = list(Sequence.objects.filter(Q(status=Sequence.PLANNED) | Q(status=Sequence.TOBEPLANNED)
  108 + | Q(status=Sequence.PENDING)))
90 self.sequences = [(sequence, ScheduleHasSequences(sequence=sequence, schedule=self.schedule)) 109 self.sequences = [(sequence, ScheduleHasSequences(sequence=sequence, schedule=self.schedule))
91 for sequence in self.sequences] 110 for sequence in self.sequences]
92 - self.log(str(len(self.sequences)) + " sequences found") 111 + if DEBUG_FILE:
  112 + self.log(str(len(self.sequences)) + " sequences found")
93 self.computeSchedule() 113 self.computeSchedule()
94 self.saveSchedule() 114 self.saveSchedule()
95 - self.log("Saving schedule with " + str(len(self.schedule.sequences.all())) + " sequences") 115 + if DEBUG_FILE:
  116 + self.log("Saving schedule with " + str(len(self.schedule.sequences.all())) + " sequences")
96 return self.schedule 117 return self.schedule
97 118
98 def saveSchedule(self) -> int: 119 def saveSchedule(self) -> int:
99 self.schedule.save() 120 self.schedule.save()
100 - for _, shs in self.sequences: 121 + for sequence, shs in self.sequences:
  122 + sequence.status = Sequence.PLANNED
101 shs.schedule = self.schedule 123 shs.schedule = self.schedule
  124 + sequence.save()
102 shs.save() 125 shs.save()
103 - self.logSchedule() 126 + if DEBUG_FILE:
  127 + self.logSchedule()
104 return 0 128 return 0
105 129
106 130
@@ -116,7 +140,8 @@ class Scheduler(IntervalManagement): @@ -116,7 +140,8 @@ class Scheduler(IntervalManagement):
116 if not SIMULATION: 140 if not SIMULATION:
117 sequence.save() 141 sequence.save()
118 self.sequences.remove((sequence, shs)) 142 self.sequences.remove((sequence, shs))
119 - self.log("Removing non eligible sequence") 143 + if DEBUG_FILE:
  144 + self.log("Removing non eligible sequence")
120 return 0 145 return 0
121 146
122 def removeInvalidSequences(self): 147 def removeInvalidSequences(self):
@@ -124,7 +149,8 @@ class Scheduler(IntervalManagement): @@ -124,7 +149,8 @@ class Scheduler(IntervalManagement):
124 if (sequence.jd1 < 0 or sequence.jd2 < 0 or 149 if (sequence.jd1 < 0 or sequence.jd2 < 0 or
125 is_nearby_less_or_equal(sequence.duration, Decimal(0)) or 150 is_nearby_less_or_equal(sequence.duration, Decimal(0)) or
126 sequence.jd2 - sequence.jd1 < sequence.duration): 151 sequence.jd2 - sequence.jd1 < sequence.duration):
127 - self.log("Removing sequence in removeInvalidSequences") 152 + if DEBUG_FILE:
  153 + self.log("Removing sequence in removeInvalidSequences")
128 self.sequences.remove((sequence, shs)) 154 self.sequences.remove((sequence, shs))
129 sequence.status = Sequence.INVALID 155 sequence.status = Sequence.INVALID
130 if not SIMULATION: 156 if not SIMULATION:
@@ -160,7 +186,8 @@ class Scheduler(IntervalManagement): @@ -160,7 +186,8 @@ class Scheduler(IntervalManagement):
160 shs.status = Sequence.PENDING 186 shs.status = Sequence.PENDING
161 self.decreaseQuota(sequence, sequence.duration) 187 self.decreaseQuota(sequence, sequence.duration)
162 else: 188 else:
163 - self.log("Removing sequence in place_sequences") 189 + if DEBUG_FILE:
  190 + self.log("Removing sequence in place_sequences")
164 shs.status = Sequence.REJECTED 191 shs.status = Sequence.REJECTED
165 shs.desc = self.REJECTED_ROOM 192 shs.desc = self.REJECTED_ROOM
166 return 0 193 return 0
src/scheduler/simulator.py
@@ -76,7 +76,7 @@ class Simulator(): @@ -76,7 +76,7 @@ class Simulator():
76 jd1 = Decimal("%.8f" % float(sequence_array[5])) 76 jd1 = Decimal("%.8f" % float(sequence_array[5]))
77 jd2 = Decimal("%.8f" % float(sequence_array[6])) 77 jd2 = Decimal("%.8f" % float(sequence_array[6]))
78 78
79 - sequence = Sequence(request=req, status=Sequence.OBSERVABLE, 79 + sequence = Sequence(request=req, status=Sequence.PLANNED,
80 name="sequence", id=id_seq, priority=priority, duration=duration, jd1=jd1, jd2=jd2, t_prefered=-1) 80 name="sequence", id=id_seq, priority=priority, duration=duration, jd1=jd1, jd2=jd2, t_prefered=-1)
81 sequences.append(sequence) 81 sequences.append(sequence)
82 82
src/scheduler/tasks.py
@@ -11,9 +11,7 @@ class scheduling(Task): @@ -11,9 +11,7 @@ class scheduling(Task):
11 def run(self, first_schedule=False, alert=False): 11 def run(self, first_schedule=False, alert=False):
12 12
13 Log.objects.create(agent='Scheduler', message='Start schedule : ' + str(datetime.datetime.now())) 13 Log.objects.create(agent='Scheduler', message='Start schedule : ' + str(datetime.datetime.now()))
14 - log.info("Scheduling start")  
15 self.scheduler = Scheduler() 14 self.scheduler = Scheduler()
16 self.scheduler.setNightLimits(secondsToJulianDate(getNightStart()), secondsToJulianDate(getNightEnd())) 15 self.scheduler.setNightLimits(secondsToJulianDate(getNightStart()), secondsToJulianDate(getNightEnd()))
17 self.scheduler.makeSchedule() 16 self.scheduler.makeSchedule()
18 - log.info("Scheduling done")  
19 Log.objects.create(agent='Scheduler', message='Scheduling finished : ' + str(datetime.datetime.now())) 17 Log.objects.create(agent='Scheduler', message='Scheduling finished : ' + str(datetime.datetime.now()))
20 \ No newline at end of file 18 \ No newline at end of file
src/scheduler/templates/scheduler/retrieve_schedule.html
@@ -63,12 +63,16 @@ @@ -63,12 +63,16 @@
63 {% for sequence in sequences %} 63 {% for sequence in sequences %}
64 <tr> 64 <tr>
65 <td> 65 <td>
66 - {% if sequence.processing == 1 %}  
67 - <img src="{% static "media/arrow_green.png" %}" alt="html5" height="30" width="30" style="margin-left:25%"/>  
68 - {% elif sequence.processing == 0 and sequence.status == "EXECUTED" %}  
69 - <img src="{% static "media/validate.jpg" %}" alt="html5" height="30" width="30" style="margin-left:25%"/> 66 + {% if sequence.0.status == "EXING" == 1 %}
  67 + <img src="{% static "media/arrow_green.png" %}" alt="html5" height="30" width="30" style="margin-left:25%"/>
  68 + {% elif sequence.0.status == "EXD" %}
  69 + <img src="{% static "media/validate.jpg" %}" alt="html5" height="30" width="30" style="margin-left:25%"/>
  70 + {% elif sequence.0.status == "PNDG" %}
  71 + <img src="{% static "media/next.png" %}" alt="html5" height="30" width="30" style="margin-left:25%"/>
  72 + {% elif sequence.0.status == "PLND" %}
  73 + <img src="{% static "media/planned.png" %}" alt="html5" height="30" width="30" style="margin-left:25%"/>
70 {% else %} 74 {% else %}
71 - <img src="{% static "media/error.png" %}" alt="{{sequence.processing}}" height="30" width="30" style="margin-left:25%"/> 75 + <img src="{% static "media/error.png" %}" alt="html5" height="30" width="30" style="margin-left:25%"/>
72 {% endif %} 76 {% endif %}
73 </td> 77 </td>
74 <td>{{ sequence.0.id }}</td> 78 <td>{{ sequence.0.id }}</td>
@@ -79,7 +83,7 @@ @@ -79,7 +83,7 @@
79 <td>{{ sequence.0.jd2|jdtodate }}</td> 83 <td>{{ sequence.0.jd2|jdtodate }}</td>
80 <td>{{ sequence.0.duration|jdtoduration }}</td> 84 <td>{{ sequence.0.duration|jdtoduration }}</td>
81 <td>{{ sequence.0.priority }}</td> 85 <td>{{ sequence.0.priority }}</td>
82 - <td>{{ sequence.1.status }}</td> 86 + <td>{{ sequence.0.status }}</td>
83 </tr> 87 </tr>
84 {% endfor %} 88 {% endfor %}
85 </tbody> 89 </tbody>
src/scheduler/views.py
@@ -10,7 +10,7 @@ SIMULATION_FILE = &#39;file:./scheduler/sequences_cador.html&#39; @@ -10,7 +10,7 @@ SIMULATION_FILE = &#39;file:./scheduler/sequences_cador.html&#39;
10 def retrieve_schedule(request): 10 def retrieve_schedule(request):
11 if (len(Schedule.objects.all()) > 0): # checking if the schedule is empty 11 if (len(Schedule.objects.all()) > 0): # checking if the schedule is empty
12 schedule = Schedule.objects.order_by("-created")[0] # Sorting Schedule 12 schedule = Schedule.objects.order_by("-created")[0] # Sorting Schedule
13 - shs_list = schedule.shs.all() # getting all the schedule has sequences references 13 + shs_list = schedule.shs.order_by("tsp") # getting all the schedule has sequences references
14 sequences = [(shs.sequence, shs) for shs in shs_list] # getting all sequences 14 sequences = [(shs.sequence, shs) for shs in shs_list] # getting all sequences
15 15
16 nb_scheduled_sequences = len(shs_list) 16 nb_scheduled_sequences = len(shs_list)
@@ -33,7 +33,7 @@ def schedule_simulation(request): @@ -33,7 +33,7 @@ def schedule_simulation(request):
33 simulator = Simulator() 33 simulator = Simulator()
34 schedule, sequences = simulator.simulate(SIMULATION_FILE) 34 schedule, sequences = simulator.simulate(SIMULATION_FILE)
35 35
36 - nb_scheduled_sequences = len([sequence for sequence in sequences if sequence[1].status != Sequence.OBSERVABLE]) 36 + nb_scheduled_sequences = len([sequence for sequence in sequences if sequence[1].status != Sequence.PLANNED])
37 executed_sequences = len([sequence for sequence in sequences if sequence[1].status == Sequence.EXECUTED]) 37 executed_sequences = len([sequence for sequence in sequences if sequence[1].status == Sequence.EXECUTED])
38 38
39 39
src/utils/JDManipulator.py
  1 +from django.conf import settings
1 import datetime 2 import datetime
2 import time 3 import time
3 from decimal import * 4 from decimal import *
@@ -5,9 +6,23 @@ from decimal import * @@ -5,9 +6,23 @@ from decimal import *
5 JD_VALUE = 86400 6 JD_VALUE = 86400
6 TIMESTAMP_JD = 2440587.500000 7 TIMESTAMP_JD = 2440587.500000
7 DAILY_SECOND = 1 / 86400 8 DAILY_SECOND = 1 / 86400
  9 +SECOND_DIV = 86400
  10 +
  11 +def getSimTime():
  12 + current_time = datetime.datetime.now()
  13 + if current_time.minute == 59:
  14 + current_time = current_time.replace(hour=(current_time.hour + 1), minute=0, second=10)
  15 + else:
  16 + if current_time.second >= 50:
  17 + current_time = current_time.replace(minute=current_time.minute + 1, second=10)
  18 + else:
  19 + current_time = current_time.replace(second=(current_time.second + 10))
  20 + return (time.mktime(current_time.timetuple()))
  21 +
  22 +SIM_TIME_START = getSimTime()
8 23
9 def JulianSeconds(value): 24 def JulianSeconds(value):
10 - return (Decimal(value * DAILY_SECOND)) 25 + return (Decimal(value) / SECOND_DIV)
11 26
12 def getPreciseCurrentTime(): 27 def getPreciseCurrentTime():
13 return (Decimal(getCurrentTime())) 28 return (Decimal(getCurrentTime()))
@@ -21,6 +36,9 @@ def getPreciseNightEnd(): @@ -21,6 +36,9 @@ def getPreciseNightEnd():
21 def secondsToJulianDate(time_seconds): 36 def secondsToJulianDate(time_seconds):
22 return (time_seconds / 86400 + TIMESTAMP_JD) 37 return (time_seconds / 86400 + TIMESTAMP_JD)
23 38
  39 +def secondsToPreciseJulianDate(time_seconds):
  40 + return (Decimal(time_seconds) / 86400 + Decimal(TIMESTAMP_JD))
  41 +
24 def julianDateToSeconds(time_julian): 42 def julianDateToSeconds(time_julian):
25 return ((time_julian - TIMESTAMP_JD) * 86400) 43 return ((time_julian - TIMESTAMP_JD) * 86400)
26 44
@@ -46,7 +64,18 @@ def getNextDefaultNightEnd(): @@ -46,7 +64,18 @@ def getNextDefaultNightEnd():
46 64
47 def getDefaultNightStart(): 65 def getDefaultNightStart():
48 current_time = datetime.datetime.now() 66 current_time = datetime.datetime.now()
49 - current_time = current_time.replace(hour=18, minute=0, second=0, microsecond=0) 67 + if settings.SIMULATOR:
  68 + if settings.SIMULATOR:
  69 + return SIM_TIME_START
  70 + if current_time.minute == 59:
  71 + current_time = current_time.replace(hour=(current_time.hour + 1), minute=0, second=10)
  72 + else:
  73 + if current_time.second > 50:
  74 + current_time = current_time.replace(minute=current_time.minute + 1, second=10)
  75 + else:
  76 + current_time = current_time.replace(second=(current_time.second + 10))
  77 + else:
  78 + current_time = current_time.replace(hour=18, minute=0, second=0, microsecond=0)
50 return (time.mktime(current_time.timetuple())) 79 return (time.mktime(current_time.timetuple()))
51 80
52 def getDefaultNightEnd(): 81 def getDefaultNightEnd():