Commit 03161a4544625c1452d7c0b2a33ea05fbde40ff8

Authored by Etienne Pallier
1 parent d467c6d8
Exists in dev

Implémenté le "abort" dans le simulateur

Attention, "pyros update" pose des questions :
répondre toujours par oui (y) et choisir l'option 1 à la fin (et entrer
un nom bidon tel que "agent" par exemple, aucune importance)
README.md
... ... @@ -67,13 +67,13 @@ This software has been tested and validated with the following configurations :
67 67 --------------------------------------------------------------------------------------------
68 68 ## LAST VERSION
69 69  
70   -Date: 26/03/2019
  70 +Date: 29/03/2019
71 71  
72 72 Author: E. Pallier
73 73  
74   -VERSION: 0.20.31
  74 +VERSION: 0.20.32
75 75  
76   -Comment: Optimisation log_agent_status() (ex update_survey())
  76 +Comment: Implémenté le "abort" dans le simulateur
77 77  
78 78 - Scenario de test :
79 79 - lancer agents A et B en mode simu (option -t): ./pyros.py -t start agentA,agentB
... ... @@ -88,6 +88,7 @@ Comment: Optimisation log_agent_status() (ex update_survey())
88 88 - pour utiliser thread ou processus : il suffit de mettre la constante RUN_IN_THREAD de AgentA (ou AgentB ou AgentX) à False ou True
89 89  
90 90 - Historique des nouveautés :
  91 + - Optimisation log_agent_status() (ex update_survey())
91 92 - AgentM (début) pour remplacer progressivement l'agent monitoring
92 93 - routine_process() : envoi commande n'est plus bloquant
93 94 - pyros.py peut lancer plusieurs agents (A et B) en même temps
... ...
devices_channel/src_device/client/device_controller_abstract.py
... ... @@ -37,7 +37,6 @@ version
37 37 title
38 38 __**DeviceController and ClientChannel classes diagram (1 - composition)**__
39 39 <i>(ClientChannel is a COMPONENT of DeviceController)</i>
40   -
41 40 end title
42 41  
43 42  
... ...
src/agent/Agent.py
... ... @@ -384,8 +384,9 @@ class Agent:
384 384 DEFAULT_CONFIG_FILE_NAME = "config_unit_simulunit1.xml"
385 385 CONFIG_DIR = "config"
386 386  
387   - # Current command to send
  387 + # Current and next command to send
388 388 cmdts = None
  389 + next_cmdts = None
389 390  
390 391 _agent_survey = None
391 392 _pending_commands = []
... ... @@ -609,59 +610,6 @@ class Agent:
609 610 if self.SIMULATOR_MODE: self.simulator_routine_process()
610 611  
611 612  
612   -
613   - def simulator_routine_process(self):
614   - """
615   - SIMULATOR MODE ONLY
616   - """
617   -
618   - SEND_A_NEW_COMMAND = False
619   - #cmdts_is_processed = False
620   -
621   - # No currently running command => send a new command
622   - if self.cmdts is None:
623   - self.cmdts = self.simulator_get_next_command_to_send()
624   - # No more command to send (from simulator) => return
625   - if self.cmdts is None: return
626   - SEND_A_NEW_COMMAND = True
627   - else:
628   - self.print(f"Waiting for end of cmd '{self.cmdts.name}' execution...")
629   - # Update cmdts fields from DB
630   - self.cmdts.refresh_from_db()
631   - # Execution was not completed => set cmd to None
632   - if self.cmdts.is_expired() or self.cmdts.is_skipped() or self.cmdts.is_killed():
633   - self.printd("Command was not completed, so I send it again")
634   - # The command was not completed, so, make a copy of it and send it again
635   - # For this, it is enough to set primary key to None,
636   - # then the send() command below will save a NEW command
637   - #self.cmdts = copy.copy(self.cmdts)
638   - self.cmdts.id = None
639   - SEND_A_NEW_COMMAND = True
640   - # cmd is executed ? => get result
641   - elif self.cmdts.is_executed():
642   - cmdts_res = self.cmdts.get_result()
643   - self.print(f"Cmd executed. Result is '{cmdts_res}'")
644   - #cmdts_is_processed = True
645   - self.cmdts = None
646   - ''' Optimisation possible pour gagner une iteration:
647   - self.cmdts = self.simulator_get_next_command_to_send()
648   - # No more command to send (from simulator) => return
649   - if self.cmdts is None: return
650   - SEND_A_NEW_COMMAND = True
651   - '''
652   -
653   - if SEND_A_NEW_COMMAND:
654   - # Send cmd (= set as pending and save)
655   - self.print(f"Send command", self.cmdts)
656   - #self.cmdts.set_as_pending()
657   - self.cmdts.send()
658   - #cmdts_is_processed = False
659   - #cmdts_res = None
660   -
661   -
662   -
663   -
664   -
665 613 """
666 614 def purge_commands(self):
667 615 ###
... ... @@ -677,7 +625,7 @@ class Agent:
677 625 #self.printd("peremption date", COMMAND_PEREMPTION_DATE_FROM_NOW)
678 626 old_commands = Command.objects.filter(
679 627 # only commands for me
680   - receiver = self.name,
  628 + recipient = self.name,
681 629 # only pending commands
682 630 sender_deposit_time__lt = COMMAND_PEREMPTION_DATE_FROM_NOW,
683 631 )
... ... @@ -857,8 +805,8 @@ class Agent:
857 805  
858 806 """
859 807 def send_command(self, cmd_name):
860   - receiver_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST
861   - Command.objects.create(sender=self.name, receiver=receiver_agent, name=cmd_name)
  808 + recipient_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST
  809 + Command.objects.create(sender=self.name, recipient=recipient_agent, name=cmd_name)
862 810 """
863 811 #def send_command(self, to_agent, cmd_type, cmd_name, cmd_args=None):
864 812 def send_command(self, to_agent, cmd_name, cmd_args=None):
... ... @@ -903,9 +851,9 @@ class Agent:
903 851 """
904 852 cmd_executing = Command.objects.filter(
905 853 # only commands for me
906   - receiver = self.name,
  854 + recipient = self.name,
907 855 # only pending commands
908   - receiver_status_code = Command.CMD_STATUS_CODES.CMD_RUNNING,
  856 + recipient_status_code = Command.CMD_STATUS_CODES.CMD_RUNNING,
909 857 ).first()
910 858 #if cmd_executing.exists():
911 859 if cmd_executing:
... ... @@ -1064,6 +1012,7 @@ class Agent:
1064 1012 """
1065 1013 assert cmd is not None
1066 1014 assert self.is_active()
  1015 +
1067 1016 self.set_status(self.STATUS_SPECIFIC_PROCESS)
1068 1017 self._current_specific_cmd = cmd
1069 1018 self.printd("Starting specific process...")
... ... @@ -1126,8 +1075,8 @@ class Agent:
1126 1075 cmd_name = next(self.SIMULATOR_COMMANDS, None)
1127 1076 #return cmd_name
1128 1077 if cmd_name is None: return None
1129   - receiver_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST
1130   - return Command(sender=self.name, receiver=receiver_agent, name=cmd_name)
  1078 + recipient_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST
  1079 + return Command(sender=self.name, recipient=recipient_agent, name=cmd_name)
1131 1080  
1132 1081 """
1133 1082 def simulator_send_next_command(self):
... ... @@ -1136,14 +1085,82 @@ class Agent:
1136 1085 cmd_name = next(self.SIMULATOR_COMMANDS, None)
1137 1086 #self.printd("next cmd is ", cmd_name)
1138 1087 if cmd_name is None: return
1139   - #Command.objects.create(sender=self.name, receiver=self.name, name=cmd_name)
1140   - receiver_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST
1141   - Command.objects.create(sender=self.name, receiver=receiver_agent, name=cmd_name)
  1088 + #Command.objects.create(sender=self.name, recipient=self.name, name=cmd_name)
  1089 + recipient_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST
  1090 + Command.objects.create(sender=self.name, recipient=recipient_agent, name=cmd_name)
1142 1091 #time.sleep(1)
1143 1092 #self._simulator_current_cmd_idx += 1
1144 1093 #self._nb_test_cmds += 1
1145 1094 """
1146 1095  
  1096 + def simulator_routine_process(self):
  1097 + """
  1098 + SIMULATOR MODE ONLY
  1099 + """
  1100 +
  1101 + # There is a current command being processed => check its status to see if finished
  1102 + if self.cmdts is not None:
  1103 + self.print(f"Waiting for end of cmd '{self.cmdts.name}' execution...")
  1104 + # Update cmdts fields from DB
  1105 + self.cmdts.refresh_from_db()
  1106 + if self.cmdts.is_pending() or self.cmdts.is_running():
  1107 + if self.next_cmdts is None:
  1108 + # If next command is "abort" then abort becomes the new current command (to be sent)
  1109 + self.next_cmdts = self.simulator_get_next_command_to_send()
  1110 + if self.next_cmdts and self.next_cmdts.name == "abort":
  1111 + self.cmdts = self.next_cmdts
  1112 + self.next_cmdts = None
  1113 + self.cmdts.send()
  1114 +
  1115 + # Current cmd is no more running
  1116 + else:
  1117 + # Execution was not completed
  1118 + #if self.cmdts.is_expired() or self.cmdts.is_skipped() or self.cmdts.is_killed():
  1119 + if self.cmdts.is_skipped() or self.cmdts.is_killed():
  1120 + self.printd("Command was not completed")
  1121 + # 2 possible scenarios:
  1122 + # - (1) Send the SAME command again
  1123 + '''
  1124 + self.printd("Command was not completed, so I send it again")
  1125 + # The command was not completed, so, make a copy of it and send it again
  1126 + # For this, it is enough to set primary key to None,
  1127 + # then the send() command below will save a NEW command
  1128 + #self.cmdts = copy.copy(self.cmdts)
  1129 + self.cmdts.id = None
  1130 + SEND_A_NEW_COMMAND = True
  1131 + '''
  1132 + # - (2) Send next command
  1133 + #self.cmdts = None
  1134 + # Execution was not complete => get result
  1135 + elif self.cmdts.is_executed():
  1136 + cmdts_res = self.cmdts.get_result()
  1137 + self.print(f"Cmd executed. Result is '{cmdts_res}'")
  1138 + #cmdts_is_processed = True
  1139 + ''' Optimisation possible pour gagner une iteration:
  1140 + self.cmdts = self.simulator_get_next_command_to_send()
  1141 + # No more command to send (from simulator) => return
  1142 + if self.cmdts is None: return
  1143 + SEND_A_NEW_COMMAND = True
  1144 + '''
  1145 + # Set cmdts to None so that a new command will be sent at next iteration
  1146 + self.cmdts = None
  1147 +
  1148 + # No currently running command => get a new command to send
  1149 + if self.cmdts is None:
  1150 + if self.next_cmdts is not None:
  1151 + self.cmdts = self.next_cmdts
  1152 + self.next_cmdts = None
  1153 + else:
  1154 + self.cmdts = self.simulator_get_next_command_to_send()
  1155 + # No more command to send (from simulator) => return
  1156 + if self.cmdts is None: return
  1157 + # Send cmd (= set as pending and save)
  1158 + self.print(f"Send command", self.cmdts)
  1159 + #self.cmdts.set_as_pending()
  1160 + self.cmdts.send()
  1161 + #cmdts_is_processed = False
  1162 + #cmdts_res = None
  1163 +
1147 1164 def simulator_test_results(self):
1148 1165 commands = self.simulator_test_results_start()
1149 1166 nb_asserted = self.simulator_test_results_main(commands)
... ...
src/agent/AgentA.py
... ... @@ -44,12 +44,14 @@ class AgentA(Agent):
44 44 # will now be able to send new commands
45 45 "go_active",
46 46  
47   - # Executed because receiver agent is now "active"
  47 + # Executed because recipient agent is now "active"
48 48 "specific1",
49   -
50   - # should abort previous command, but does not because specific1 is already executed
  49 + # should abort previous command (specific1)
51 50 "abort",
52 51  
  52 + # Executed completely because no abort
  53 + "specific2",
  54 +
53 55 # fully executed, result is 7
54 56 "eval 4+3",
55 57  
... ... @@ -199,6 +201,9 @@ class AgentA(Agent):
199 201 nb_asserted+=1
200 202 """
201 203 if cmd.name == "specific1":
  204 + assert cmd.is_killed()
  205 + nb_asserted+=1
  206 + if cmd.name == "specific2":
202 207 assert cmd.is_executed()
203 208 assert cmd.result == "in step #5/5"
204 209 nb_asserted+=1
... ...
src/common/models.py
... ... @@ -213,10 +213,114 @@ class Request(models.Model):
213 213 ------------------------
214 214 """
215 215  
  216 +
  217 +class AgentSurvey(models.Model):
  218 + """
  219 + | id | name | created | updated | validity_duration (default=1mn) | mode (active/idle) | status (launch/init/loop/exit/...) |
  220 + """
  221 +
  222 + # Statuses
  223 + #STATUSES = Choices('new', 'verified', 'published')
  224 + STATUS_LAUNCH = "LAUNCHED"
  225 + STATUS_INIT = "INITIALIZING"
  226 + STATUS_MAIN_LOOP = "IN_MAIN_LOOP"
  227 + STATUS_PROCESS_LOOP = "IN_PROCESS_LOOP"
  228 + STATUS_EXIT = "EXITING"
  229 +
  230 + # Modes
  231 + MODE_ACTIVE = "ACTIVE"
  232 + MODE_IDLE = "IDLE"
  233 +
  234 + MODE_CHOICES = (
  235 + (MODE_ACTIVE, 'Active mode'),
  236 + (MODE_IDLE, 'Idle mode'),
  237 + )
  238 +
  239 + STATUS_CHOICES = (
  240 + (STATUS_LAUNCH, "LAUNCHED"),
  241 + (STATUS_INIT, "INITIALIZING"),
  242 + (STATUS_MAIN_LOOP, "IN_MAIN_LOOP"),
  243 + (STATUS_PROCESS_LOOP, "IN_PROCESS_LOOP"),
  244 + (STATUS_EXIT, "EXITING"),
  245 + )
  246 +
  247 + name = models.CharField(max_length=50, unique=True)
  248 + #name = models.CharField(max_length=50, blank=True, null=True, unique=True)
  249 + #created = models.DateTimeField(blank=True, null=True, auto_now_add=True)
  250 + created = models.DateTimeField(blank=True, null=True, auto_now_add=True)
  251 + updated = models.DateTimeField(blank=True, null=True, auto_now=True)
  252 + validity_duration = models.PositiveIntegerField(default=90)
  253 + #validity_duration = models.DurationField(default=90)
  254 + mode = models.CharField('agent mode', max_length=15, blank=True, choices=MODE_CHOICES)
  255 + status = models.CharField(max_length=15, blank=True, choices=STATUS_CHOICES)
  256 +
  257 + class Meta:
  258 + managed = True
  259 + db_table = 'agent_survey'
  260 + #verbose_name = "agent survey"
  261 + #verbose_name_plural = "agents survey"
  262 +
  263 + def __str__(self):
  264 + return (f"Agent {self.name} at {self.updated} in mode {self.mode} and status {self.status}")
  265 +
  266 +
  267 +class Album(models.Model):
  268 + sequence = models.ForeignKey(
  269 + 'Sequence', on_delete=models.CASCADE, related_name="albums")
  270 + detector = models.ForeignKey(
  271 + 'Detector', models.DO_NOTHING, related_name="albums", blank=True, null=True)
  272 + name = models.CharField(max_length=45, blank=True, null=True)
  273 + desc = models.TextField(blank=True, null=True)
  274 + created = models.DateTimeField(blank=True, null=True, auto_now_add=True)
  275 + updated = models.DateTimeField(blank=True, null=True, auto_now=True)
  276 + complete = models.BooleanField(default=False)
  277 +
  278 + class Meta:
  279 + managed = True
  280 + db_table = 'album'
  281 + #verbose_name_plural = "Albums"
  282 +
  283 + def __str__(self):
  284 + return (str(self.name))
  285 +
  286 +
  287 +class Alert(Request):
  288 + request = models.OneToOneField('Request', on_delete=models.CASCADE, default='', parent_link=True)
  289 + strategyobs = models.ForeignKey(
  290 + 'StrategyObs', models.DO_NOTHING, related_name="alerts", blank=True, null=True)
  291 + voevent_file = models.CharField(max_length=45, blank=True, null=True)
  292 + author = models.CharField(max_length=45, blank=True, null=True)
  293 + burst_jd = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True)
  294 + burst_ra = models.FloatField(max_length=45, blank=True, null=True)
  295 + burst_dec = models.FloatField(max_length=45, blank=True, null=True)
  296 + astro_coord_system = models.CharField(max_length=45, blank=True, null=True)
  297 + jd_send = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True)
  298 + jd_received = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True)
  299 + trig_id = models.IntegerField(blank=True, null=True)
  300 + error_radius = models.FloatField(max_length=45, blank=True, null=True)
  301 + defly_not_grb = models.BooleanField(default=False)
  302 + editor = models.CharField(max_length=45, blank=True, null=True)
  303 + soln_status = models.CharField(max_length=45, blank=True, null=True)
  304 + pkt_ser_num = models.IntegerField(blank=True, null=True)
  305 +
  306 + class Meta:
  307 + managed = True
  308 + db_table = 'alert'
  309 +
  310 + def __str__(self):
  311 + return str(self.trig_id)
  312 +
  313 + def request_name(self):
  314 + return self.__str__()
  315 +
  316 + request_name.short_description = "Name"
  317 +
  318 +
  319 +
216 320 class Command(models.Model):
217 321  
218 322 """
219   - | id | sender | receiver | name | validity_duration_sec (default=60) | sender_deposit_time | receiver_read_time
  323 + | id | sender | recipient | name | validity_duration (default=60) | s_deposit_time | r_read_time
220 324 """
221 325  
222 326 # -------------- Command CONSTANTS --------------
... ... @@ -254,18 +358,18 @@ class Command(models.Model):
254 358  
255 359 #sender = models.CharField(max_length=50, blank=True, null=True, unique=True)
256 360 sender = models.CharField(max_length=50, help_text='sender agent name')
257   - receiver = models.CharField(max_length=50, help_text='receiver agent name')
  361 + recipient = models.CharField(max_length=50, help_text='recipient agent name')
258 362 name = models.CharField(max_length=400, help_text='command name')
259   - validity_duration_sec = models.PositiveIntegerField(default=COMMANDS_VALIDITY_DURATION_SEC_DEFAULT)
  363 + validity_duration = models.PositiveIntegerField('(in sec)', default=COMMANDS_VALIDITY_DURATION_SEC_DEFAULT)
260 364 # Automatically set at table line creation (line created by the sender)
261   - sender_deposit_time = models.DateTimeField(blank=True, null=True, auto_now_add=True)
262   - # Set by the receiver :
  365 + s_deposit_time = models.DateTimeField(blank=True, null=True, auto_now_add=True)
  366 + # Set by the recipient :
263 367 # - at reading time
264   - receiver_read_time = models.DateTimeField(null=True)
  368 + r_read_time = models.DateTimeField(null=True)
265 369 # - after execution
266   - receiver_processed_time = models.DateTimeField(null=True)
267   - receiver_status_code = models.CharField(choices = CMD_STATUS_CODES, default=CMD_STATUS_CODES.CMD_PENDING, max_length=20)
268   - #receiver_status_code = models.IntegerField(choices=CMD_STATUS_CODES, default=RSCODE_PENDING)
  370 + r_processed_time = models.DateTimeField(null=True)
  371 + r_status_code = models.CharField(choices = CMD_STATUS_CODES, default=CMD_STATUS_CODES.CMD_PENDING, max_length=20)
  372 + #r_status_code = models.IntegerField(choices=CMD_STATUS_CODES, default=RSCODE_PENDING)
269 373 # TODO: maybe à mettre au format json (key:value)
270 374 result = models.CharField(max_length=400, blank=True)
271 375  
... ... @@ -281,7 +385,7 @@ class Command(models.Model):
281 385 """
282 386 @classmethod
283 387 def send(cls, cmd:Command):
284   - cls.objects.create(sender=cmd.name, receiver=cmd.receiver, name=cmd.name)
  388 + cls.objects.create(sender=cmd.name, recipient=cmd.recipient, name=cmd.name)
285 389 """
286 390 @classmethod
287 391 def send_command(cls, from_agent, to_agent, cmd_name, cmd_args=None):
... ... @@ -289,8 +393,8 @@ class Command(models.Model):
289 393 ex: send("AgentA",“AgentB”,"EVAL”,“3+4”)
290 394 """
291 395 if cmd_args: cmd_name += ' '+cmd_args
292   - #Command.objects.create(sender=self.name, receiver=receiver_agent, name=cmd_name)
293   - cmd = cls(sender=from_agent, receiver=to_agent, name=cmd_name)
  396 + #Command.objects.create(sender=self.name, recipient=r_agent, name=cmd_name)
  397 + cmd = cls(sender=from_agent, recipient=to_agent, name=cmd_name)
294 398 cmd.send()
295 399 #cmd.set_as_pending()
296 400 #cmd.save()
... ... @@ -305,11 +409,11 @@ class Command(models.Model):
305 409 print("Delete (false) 'running' command if exists:")
306 410 running_commands = cls.objects.filter(
307 411 # only commands for agent agent_name
308   - receiver = agent_name,
  412 + recipient = agent_name,
309 413 # only running commands
310   - receiver_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING,
  414 + r_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING,
311 415 # only not expired commands
312   - #sender_deposit_time__gte = cls.get_peremption_date_from_now(),
  416 + #s_deposit_time__gte = cls.get_peremption_date_from_now(),
313 417 )
314 418 if running_commands:
315 419 Command.show_commands(running_commands)
... ... @@ -331,11 +435,11 @@ class Command(models.Model):
331 435 #print("now_minus_2sec", now_minus_2sec)
332 436 pending_commands = cls.objects.filter(
333 437 # only commands for agent agent_name
334   - receiver = agent_name,
  438 + recipient = agent_name,
335 439 # only running commands
336   - receiver_status_code = cls.CMD_STATUS_CODES.CMD_PENDING,
  440 + r_status_code = cls.CMD_STATUS_CODES.CMD_PENDING,
337 441 # except very recent commands : take only commands that are more than 2 sec old
338   - sender_deposit_time__lt = now_minus_2sec
  442 + s_deposit_time__lt = now_minus_2sec
339 443 )
340 444 if pending_commands:
341 445 Command.show_commands(pending_commands)
... ... @@ -348,16 +452,16 @@ class Command(models.Model):
348 452 return cls.objects.filter(
349 453 # only pending commands
350 454 # but also including the currently running command
351   - Q(receiver_status_code = cls.CMD_STATUS_CODES.CMD_PENDING) | Q(receiver_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING),
  455 + Q(r_status_code = cls.CMD_STATUS_CODES.CMD_PENDING) | Q(r_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING),
352 456 # only commands for agent agent_name
353   - receiver = agent_name,
  457 + recipient = agent_name,
354 458 # only not expired commands
355   - #sender_deposit_time__gte = cls.get_peremption_date_from_now(),
356   - ).order_by("sender_deposit_time")
  459 + #s_deposit_time__gte = cls.get_peremption_date_from_now(),
  460 + ).order_by("s_deposit_time")
357 461  
358 462 @classmethod
359 463 def get_commands_sent_to_agent(cls, agent_name):
360   - return cls.objects.filter(receiver=agent_name)
  464 + return cls.objects.filter(recipient=agent_name)
361 465  
362 466 @classmethod
363 467 def get_commands_sent_by_agent(cls, agent_name):
... ... @@ -367,7 +471,7 @@ class Command(models.Model):
367 471 def get_last_N_commands_sent_to_agent(cls, agent_name, N):
368 472 #filter(since=since)
369 473 #return cls.objects.all()[:nb_cmds]
370   - #commands = cls.objects.filter(receiver = agent_name).order_by('-id')[:N]
  474 + #commands = cls.objects.filter(recipient = agent_name).order_by('-id')[:N]
371 475 commands = cls.get_commands_sent_to_agent(agent_name).order_by('-id')[:N]
372 476 return list(reversed(commands))
373 477  
... ... @@ -375,7 +479,7 @@ class Command(models.Model):
375 479 def get_last_N_commands_sent_by_agent(cls, agent_name, N):
376 480 #filter(since=since)
377 481 #return cls.objects.all()[:nb_cmds]
378   - #commands = cls.objects.filter(receiver = agent_name).order_by('-id')[:N]
  482 + #commands = cls.objects.filter(recipient = agent_name).order_by('-id')[:N]
379 483 commands = cls.get_commands_sent_by_agent(agent_name).order_by('-id')[:N]
380 484 return list(reversed(commands))
381 485  
... ... @@ -392,11 +496,11 @@ class Command(models.Model):
392 496 #print("peremption date", COMMAND_PEREMPTION_DATE_FROM_NOW)
393 497 old_commands = cls.objects.filter(
394 498 # only commands for agent agent_name
395   - receiver = agent_name,
  499 + recipient = agent_name,
396 500 # only expired commands
397   - sender_deposit_time__lt = cls.get_peremption_date_from_now(),
  501 + s_deposit_time__lt = cls.get_peremption_date_from_now(),
398 502 ).exclude(
399   - receiver_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING
  503 + r_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING
400 504 )
401 505 if old_commands.exists():
402 506 print("Found old commands to delete:")
... ... @@ -419,7 +523,7 @@ class Command(models.Model):
419 523 # -------------- Command INSTANCE METHODS --------------
420 524  
421 525 def __str__(self):
422   - return (f"Commmand '{self.name}' ({self.receiver_status_code}) sent by agent {self.sender} to agent {self.receiver} at {self.sender_deposit_time}")
  526 + return (f"Commmand '{self.name}' ({self.r_status_code}) sent by agent {self.sender} to agent {self.recipient} at {self.s_deposit_time}")
423 527  
424 528 # --- BOOLEAN (test) functions ---
425 529  
... ... @@ -439,30 +543,30 @@ class Command(models.Model):
439 543 "CMD_OUTOFDATE" # cde périmée
440 544  
441 545 def is_read(self):
442   - return self.receiver_read_time is not None
  546 + return self.r_read_time is not None
443 547  
444 548 def is_pending(self):
445   - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_PENDING
  549 + return self.r_status_code == self.CMD_STATUS_CODES.CMD_PENDING
446 550  
447 551 def is_running(self):
448   - #return (datetime.utcnow() - self.sender_deposit_time) > timedelta(seconds = self.validity_duration_sec)
449   - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_RUNNING
  552 + #return (datetime.utcnow() - self.s_deposit_time) > timedelta(seconds = self.validity_duration)
  553 + return self.r_status_code == self.CMD_STATUS_CODES.CMD_RUNNING
450 554  
451 555 def is_executed(self):
452   - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_EXECUTED
  556 + return self.r_status_code == self.CMD_STATUS_CODES.CMD_EXECUTED
453 557  
454 558 def is_skipped(self):
455   - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_SKIPPED
  559 + return self.r_status_code == self.CMD_STATUS_CODES.CMD_SKIPPED
456 560  
457 561 def is_killed(self):
458   - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_KILLED
  562 + return self.r_status_code == self.CMD_STATUS_CODES.CMD_KILLED
459 563  
460 564 def is_expired(self):
461   - #return (datetime.utcnow() - self.sender_deposit_time) > timedelta(seconds = self.validity_duration_sec)
462   - return (datetime.utcnow().astimezone() - self.sender_deposit_time) > timedelta(seconds = self.validity_duration_sec)
  565 + #return (datetime.utcnow() - self.s_deposit_time) > timedelta(seconds = self.validity_duration)
  566 + return (datetime.utcnow().astimezone() - self.s_deposit_time) > timedelta(seconds = self.validity_duration)
463 567 """
464   - elapsed_time = cmd.receiver_read_time - cmd.sender_deposit_time
465   - max_time = timedelta(seconds = cmd.validity_duration_sec)
  568 + elapsed_time = cmd.r_read_time - cmd.s_deposit_time
  569 + max_time = timedelta(seconds = cmd.validity_duration)
466 570 print(f"Elapsed time is {elapsed_time}, (max is {max_time})")
467 571 if elapsed_time > max_time:
468 572 """
... ... @@ -481,21 +585,21 @@ class Command(models.Model):
481 585 self.save()
482 586  
483 587 def set_read_time(self):
484   - self.receiver_read_time = datetime.utcnow().astimezone()
  588 + self.r_read_time = datetime.utcnow().astimezone()
485 589 # Optimization: update only 1 field
486   - self.save(update_fields=["receiver_read_time"])
  590 + self.save(update_fields=["r_read_time"])
487 591  
488 592 def set_as_processed(self):
489 593 print(f"- Set command {self.name} as processed")
490 594 #print(self)
491   - self.receiver_status_code = self.CMD_STATUS_CODES.CMD_EXECUTED
492   - self.receiver_processed_time = datetime.utcnow().astimezone()
  595 + self.r_status_code = self.CMD_STATUS_CODES.CMD_EXECUTED
  596 + self.r_processed_time = datetime.utcnow().astimezone()
493 597 self.save()
494 598 # Optimization: update the related fields, but does not work, why ?
495   - ##self.save(update_fields=["receiver_status_code", "receiver_processed_time"])
  599 + ##self.save(update_fields=["r_status_code", "r_processed_time"])
496 600  
497 601 def set_as_outofdate(self):
498   - print(f"- Set this command as expired (older than its validity duration of {self.validity_duration_sec}s): {self}")
  602 + print(f"- Set this command as expired (older than its validity duration of {self.validity_duration}s): {self}")
499 603 self.set_status_to(self.CMD_STATUS_CODES.CMD_OUTOFDATE)
500 604  
501 605 def set_as_pending(self):
... ... @@ -518,112 +622,10 @@ class Command(models.Model):
518 622 '''
519 623  
520 624 def set_status_to(self, status:str):
521   - self.receiver_status_code = status
  625 + self.r_status_code = status
522 626 self.save()
523 627 # Optimization, but does not work, why ?...
524   - ##self.save(update_fields=["receiver_status_code"])
525   -
526   -
527   -class AgentSurvey(models.Model):
528   - """
529   - | id | name | created | updated | validity_duration_sec (default=1mn) | mode (active/idle) | status (launch/init/loop/exit/...) |
530   - """
531   -
532   - # Statuses
533   - #STATUSES = Choices('new', 'verified', 'published')
534   - STATUS_LAUNCH = "LAUNCHED"
535   - STATUS_INIT = "INITIALIZING"
536   - STATUS_MAIN_LOOP = "IN_MAIN_LOOP"
537   - STATUS_PROCESS_LOOP = "IN_PROCESS_LOOP"
538   - STATUS_EXIT = "EXITING"
539   -
540   - # Modes
541   - MODE_ACTIVE = "ACTIVE"
542   - MODE_IDLE = "IDLE"
543   -
544   - MODE_CHOICES = (
545   - (MODE_ACTIVE, 'Active mode'),
546   - (MODE_IDLE, 'Idle mode'),
547   - )
548   -
549   - STATUS_CHOICES = (
550   - (STATUS_LAUNCH, "LAUNCHED"),
551   - (STATUS_INIT, "INITIALIZING"),
552   - (STATUS_MAIN_LOOP, "IN_MAIN_LOOP"),
553   - (STATUS_PROCESS_LOOP, "IN_PROCESS_LOOP"),
554   - (STATUS_EXIT, "EXITING"),
555   - )
556   -
557   - name = models.CharField(max_length=50, unique=True)
558   - #name = models.CharField(max_length=50, blank=True, null=True, unique=True)
559   - #created = models.DateTimeField(blank=True, null=True, auto_now_add=True)
560   - created = models.DateTimeField(blank=True, null=True, auto_now_add=True)
561   - updated = models.DateTimeField(blank=True, null=True, auto_now=True)
562   - validity_duration_sec = models.PositiveIntegerField(default=90)
563   - #validity_duration_sec = models.DurationField(default=90)
564   - mode = models.CharField('agent mode', max_length=15, blank=True, choices=MODE_CHOICES)
565   - status = models.CharField(max_length=15, blank=True, choices=STATUS_CHOICES)
566   -
567   - class Meta:
568   - managed = True
569   - db_table = 'agent_survey'
570   - #verbose_name = "agent survey"
571   - #verbose_name_plural = "agents survey"
572   -
573   - def __str__(self):
574   - return (f"Agent {self.name} at {self.updated} in mode {self.mode} and status {self.status}")
575   -
576   -
577   -class Album(models.Model):
578   - sequence = models.ForeignKey(
579   - 'Sequence', on_delete=models.CASCADE, related_name="albums")
580   - detector = models.ForeignKey(
581   - 'Detector', models.DO_NOTHING, related_name="albums", blank=True, null=True)
582   - name = models.CharField(max_length=45, blank=True, null=True)
583   - desc = models.TextField(blank=True, null=True)
584   - created = models.DateTimeField(blank=True, null=True, auto_now_add=True)
585   - updated = models.DateTimeField(blank=True, null=True, auto_now=True)
586   - complete = models.BooleanField(default=False)
587   -
588   - class Meta:
589   - managed = True
590   - db_table = 'album'
591   - #verbose_name_plural = "Albums"
592   -
593   - def __str__(self):
594   - return (str(self.name))
595   -
596   -
597   -class Alert(Request):
598   - request = models.OneToOneField('Request', on_delete=models.CASCADE, default='', parent_link=True)
599   - strategyobs = models.ForeignKey(
600   - 'StrategyObs', models.DO_NOTHING, related_name="alerts", blank=True, null=True)
601   - voevent_file = models.CharField(max_length=45, blank=True, null=True)
602   - author = models.CharField(max_length=45, blank=True, null=True)
603   - burst_jd = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True)
604   - burst_ra = models.FloatField(max_length=45, blank=True, null=True)
605   - burst_dec = models.FloatField(max_length=45, blank=True, null=True)
606   - astro_coord_system = models.CharField(max_length=45, blank=True, null=True)
607   - jd_send = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True)
608   - jd_received = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True)
609   - trig_id = models.IntegerField(blank=True, null=True)
610   - error_radius = models.FloatField(max_length=45, blank=True, null=True)
611   - defly_not_grb = models.BooleanField(default=False)
612   - editor = models.CharField(max_length=45, blank=True, null=True)
613   - soln_status = models.CharField(max_length=45, blank=True, null=True)
614   - pkt_ser_num = models.IntegerField(blank=True, null=True)
615   -
616   - class Meta:
617   - managed = True
618   - db_table = 'alert'
619   -
620   - def __str__(self):
621   - return str(self.trig_id)
622   -
623   - def request_name(self):
624   - return self.__str__()
625   -
626   - request_name.short_description = "Name"
  628 + ##self.save(update_fields=["r_status_code"])
627 629  
628 630  
629 631  
... ...