From 03161a4544625c1452d7c0b2a33ea05fbde40ff8 Mon Sep 17 00:00:00 2001 From: Etienne Pallier Date: Fri, 29 Mar 2019 16:34:17 +0100 Subject: [PATCH] Implémenté le "abort" dans le simulateur --- README.md | 7 ++++--- devices_channel/src_device/client/device_controller_abstract.py | 1 - src/agent/Agent.py | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------- src/agent/AgentA.py | 11 ++++++++--- src/common/models.py | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------ 5 files changed, 245 insertions(+), 221 deletions(-) diff --git a/README.md b/README.md index 71807bb..e7c51c7 100644 --- a/README.md +++ b/README.md @@ -67,13 +67,13 @@ This software has been tested and validated with the following configurations : -------------------------------------------------------------------------------------------- ## LAST VERSION -Date: 26/03/2019 +Date: 29/03/2019 Author: E. Pallier -VERSION: 0.20.31 +VERSION: 0.20.32 -Comment: Optimisation log_agent_status() (ex update_survey()) +Comment: Implémenté le "abort" dans le simulateur - Scenario de test : - 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()) - pour utiliser thread ou processus : il suffit de mettre la constante RUN_IN_THREAD de AgentA (ou AgentB ou AgentX) à False ou True - Historique des nouveautés : + - Optimisation log_agent_status() (ex update_survey()) - AgentM (début) pour remplacer progressivement l'agent monitoring - routine_process() : envoi commande n'est plus bloquant - pyros.py peut lancer plusieurs agents (A et B) en même temps diff --git a/devices_channel/src_device/client/device_controller_abstract.py b/devices_channel/src_device/client/device_controller_abstract.py index b434eb8..b36bf93 100755 --- a/devices_channel/src_device/client/device_controller_abstract.py +++ b/devices_channel/src_device/client/device_controller_abstract.py @@ -37,7 +37,6 @@ version title __**DeviceController and ClientChannel classes diagram (1 - composition)**__ (ClientChannel is a COMPONENT of DeviceController) - end title diff --git a/src/agent/Agent.py b/src/agent/Agent.py index c2a7d4c..6946bf4 100755 --- a/src/agent/Agent.py +++ b/src/agent/Agent.py @@ -384,8 +384,9 @@ class Agent: DEFAULT_CONFIG_FILE_NAME = "config_unit_simulunit1.xml" CONFIG_DIR = "config" - # Current command to send + # Current and next command to send cmdts = None + next_cmdts = None _agent_survey = None _pending_commands = [] @@ -609,59 +610,6 @@ class Agent: if self.SIMULATOR_MODE: self.simulator_routine_process() - - def simulator_routine_process(self): - """ - SIMULATOR MODE ONLY - """ - - SEND_A_NEW_COMMAND = False - #cmdts_is_processed = False - - # No currently running command => send a new command - if self.cmdts is None: - self.cmdts = self.simulator_get_next_command_to_send() - # No more command to send (from simulator) => return - if self.cmdts is None: return - SEND_A_NEW_COMMAND = True - else: - self.print(f"Waiting for end of cmd '{self.cmdts.name}' execution...") - # Update cmdts fields from DB - self.cmdts.refresh_from_db() - # Execution was not completed => set cmd to None - if self.cmdts.is_expired() or self.cmdts.is_skipped() or self.cmdts.is_killed(): - self.printd("Command was not completed, so I send it again") - # The command was not completed, so, make a copy of it and send it again - # For this, it is enough to set primary key to None, - # then the send() command below will save a NEW command - #self.cmdts = copy.copy(self.cmdts) - self.cmdts.id = None - SEND_A_NEW_COMMAND = True - # cmd is executed ? => get result - elif self.cmdts.is_executed(): - cmdts_res = self.cmdts.get_result() - self.print(f"Cmd executed. Result is '{cmdts_res}'") - #cmdts_is_processed = True - self.cmdts = None - ''' Optimisation possible pour gagner une iteration: - self.cmdts = self.simulator_get_next_command_to_send() - # No more command to send (from simulator) => return - if self.cmdts is None: return - SEND_A_NEW_COMMAND = True - ''' - - if SEND_A_NEW_COMMAND: - # Send cmd (= set as pending and save) - self.print(f"Send command", self.cmdts) - #self.cmdts.set_as_pending() - self.cmdts.send() - #cmdts_is_processed = False - #cmdts_res = None - - - - - """ def purge_commands(self): ### @@ -677,7 +625,7 @@ class Agent: #self.printd("peremption date", COMMAND_PEREMPTION_DATE_FROM_NOW) old_commands = Command.objects.filter( # only commands for me - receiver = self.name, + recipient = self.name, # only pending commands sender_deposit_time__lt = COMMAND_PEREMPTION_DATE_FROM_NOW, ) @@ -857,8 +805,8 @@ class Agent: """ def send_command(self, cmd_name): - receiver_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST - Command.objects.create(sender=self.name, receiver=receiver_agent, name=cmd_name) + recipient_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST + Command.objects.create(sender=self.name, recipient=recipient_agent, name=cmd_name) """ #def send_command(self, to_agent, cmd_type, cmd_name, cmd_args=None): def send_command(self, to_agent, cmd_name, cmd_args=None): @@ -903,9 +851,9 @@ class Agent: """ cmd_executing = Command.objects.filter( # only commands for me - receiver = self.name, + recipient = self.name, # only pending commands - receiver_status_code = Command.CMD_STATUS_CODES.CMD_RUNNING, + recipient_status_code = Command.CMD_STATUS_CODES.CMD_RUNNING, ).first() #if cmd_executing.exists(): if cmd_executing: @@ -1064,6 +1012,7 @@ class Agent: """ assert cmd is not None assert self.is_active() + self.set_status(self.STATUS_SPECIFIC_PROCESS) self._current_specific_cmd = cmd self.printd("Starting specific process...") @@ -1126,8 +1075,8 @@ class Agent: cmd_name = next(self.SIMULATOR_COMMANDS, None) #return cmd_name if cmd_name is None: return None - receiver_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST - return Command(sender=self.name, receiver=receiver_agent, name=cmd_name) + recipient_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST + return Command(sender=self.name, recipient=recipient_agent, name=cmd_name) """ def simulator_send_next_command(self): @@ -1136,14 +1085,82 @@ class Agent: cmd_name = next(self.SIMULATOR_COMMANDS, None) #self.printd("next cmd is ", cmd_name) if cmd_name is None: return - #Command.objects.create(sender=self.name, receiver=self.name, name=cmd_name) - receiver_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST - Command.objects.create(sender=self.name, receiver=receiver_agent, name=cmd_name) + #Command.objects.create(sender=self.name, recipient=self.name, name=cmd_name) + recipient_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST + Command.objects.create(sender=self.name, recipient=recipient_agent, name=cmd_name) #time.sleep(1) #self._simulator_current_cmd_idx += 1 #self._nb_test_cmds += 1 """ + def simulator_routine_process(self): + """ + SIMULATOR MODE ONLY + """ + + # There is a current command being processed => check its status to see if finished + if self.cmdts is not None: + self.print(f"Waiting for end of cmd '{self.cmdts.name}' execution...") + # Update cmdts fields from DB + self.cmdts.refresh_from_db() + if self.cmdts.is_pending() or self.cmdts.is_running(): + if self.next_cmdts is None: + # If next command is "abort" then abort becomes the new current command (to be sent) + self.next_cmdts = self.simulator_get_next_command_to_send() + if self.next_cmdts and self.next_cmdts.name == "abort": + self.cmdts = self.next_cmdts + self.next_cmdts = None + self.cmdts.send() + + # Current cmd is no more running + else: + # Execution was not completed + #if self.cmdts.is_expired() or self.cmdts.is_skipped() or self.cmdts.is_killed(): + if self.cmdts.is_skipped() or self.cmdts.is_killed(): + self.printd("Command was not completed") + # 2 possible scenarios: + # - (1) Send the SAME command again + ''' + self.printd("Command was not completed, so I send it again") + # The command was not completed, so, make a copy of it and send it again + # For this, it is enough to set primary key to None, + # then the send() command below will save a NEW command + #self.cmdts = copy.copy(self.cmdts) + self.cmdts.id = None + SEND_A_NEW_COMMAND = True + ''' + # - (2) Send next command + #self.cmdts = None + # Execution was not complete => get result + elif self.cmdts.is_executed(): + cmdts_res = self.cmdts.get_result() + self.print(f"Cmd executed. Result is '{cmdts_res}'") + #cmdts_is_processed = True + ''' Optimisation possible pour gagner une iteration: + self.cmdts = self.simulator_get_next_command_to_send() + # No more command to send (from simulator) => return + if self.cmdts is None: return + SEND_A_NEW_COMMAND = True + ''' + # Set cmdts to None so that a new command will be sent at next iteration + self.cmdts = None + + # No currently running command => get a new command to send + if self.cmdts is None: + if self.next_cmdts is not None: + self.cmdts = self.next_cmdts + self.next_cmdts = None + else: + self.cmdts = self.simulator_get_next_command_to_send() + # No more command to send (from simulator) => return + if self.cmdts is None: return + # Send cmd (= set as pending and save) + self.print(f"Send command", self.cmdts) + #self.cmdts.set_as_pending() + self.cmdts.send() + #cmdts_is_processed = False + #cmdts_res = None + def simulator_test_results(self): commands = self.simulator_test_results_start() nb_asserted = self.simulator_test_results_main(commands) diff --git a/src/agent/AgentA.py b/src/agent/AgentA.py index de068c3..3c4c7a2 100755 --- a/src/agent/AgentA.py +++ b/src/agent/AgentA.py @@ -44,12 +44,14 @@ class AgentA(Agent): # will now be able to send new commands "go_active", - # Executed because receiver agent is now "active" + # Executed because recipient agent is now "active" "specific1", - - # should abort previous command, but does not because specific1 is already executed + # should abort previous command (specific1) "abort", + # Executed completely because no abort + "specific2", + # fully executed, result is 7 "eval 4+3", @@ -199,6 +201,9 @@ class AgentA(Agent): nb_asserted+=1 """ if cmd.name == "specific1": + assert cmd.is_killed() + nb_asserted+=1 + if cmd.name == "specific2": assert cmd.is_executed() assert cmd.result == "in step #5/5" nb_asserted+=1 diff --git a/src/common/models.py b/src/common/models.py index 82f20bd..a24f8b6 100644 --- a/src/common/models.py +++ b/src/common/models.py @@ -213,10 +213,114 @@ class Request(models.Model): ------------------------ """ + +class AgentSurvey(models.Model): + """ + | id | name | created | updated | validity_duration (default=1mn) | mode (active/idle) | status (launch/init/loop/exit/...) | + """ + + # Statuses + #STATUSES = Choices('new', 'verified', 'published') + STATUS_LAUNCH = "LAUNCHED" + STATUS_INIT = "INITIALIZING" + STATUS_MAIN_LOOP = "IN_MAIN_LOOP" + STATUS_PROCESS_LOOP = "IN_PROCESS_LOOP" + STATUS_EXIT = "EXITING" + + # Modes + MODE_ACTIVE = "ACTIVE" + MODE_IDLE = "IDLE" + + MODE_CHOICES = ( + (MODE_ACTIVE, 'Active mode'), + (MODE_IDLE, 'Idle mode'), + ) + + STATUS_CHOICES = ( + (STATUS_LAUNCH, "LAUNCHED"), + (STATUS_INIT, "INITIALIZING"), + (STATUS_MAIN_LOOP, "IN_MAIN_LOOP"), + (STATUS_PROCESS_LOOP, "IN_PROCESS_LOOP"), + (STATUS_EXIT, "EXITING"), + ) + + name = models.CharField(max_length=50, unique=True) + #name = models.CharField(max_length=50, blank=True, null=True, unique=True) + #created = models.DateTimeField(blank=True, null=True, auto_now_add=True) + created = models.DateTimeField(blank=True, null=True, auto_now_add=True) + updated = models.DateTimeField(blank=True, null=True, auto_now=True) + validity_duration = models.PositiveIntegerField(default=90) + #validity_duration = models.DurationField(default=90) + mode = models.CharField('agent mode', max_length=15, blank=True, choices=MODE_CHOICES) + status = models.CharField(max_length=15, blank=True, choices=STATUS_CHOICES) + + class Meta: + managed = True + db_table = 'agent_survey' + #verbose_name = "agent survey" + #verbose_name_plural = "agents survey" + + def __str__(self): + return (f"Agent {self.name} at {self.updated} in mode {self.mode} and status {self.status}") + + +class Album(models.Model): + sequence = models.ForeignKey( + 'Sequence', on_delete=models.CASCADE, related_name="albums") + detector = models.ForeignKey( + 'Detector', models.DO_NOTHING, related_name="albums", blank=True, null=True) + name = models.CharField(max_length=45, blank=True, null=True) + desc = models.TextField(blank=True, null=True) + created = models.DateTimeField(blank=True, null=True, auto_now_add=True) + updated = models.DateTimeField(blank=True, null=True, auto_now=True) + complete = models.BooleanField(default=False) + + class Meta: + managed = True + db_table = 'album' + #verbose_name_plural = "Albums" + + def __str__(self): + return (str(self.name)) + + +class Alert(Request): + request = models.OneToOneField('Request', on_delete=models.CASCADE, default='', parent_link=True) + strategyobs = models.ForeignKey( + 'StrategyObs', models.DO_NOTHING, related_name="alerts", blank=True, null=True) + voevent_file = models.CharField(max_length=45, blank=True, null=True) + author = models.CharField(max_length=45, blank=True, null=True) + burst_jd = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True) + burst_ra = models.FloatField(max_length=45, blank=True, null=True) + burst_dec = models.FloatField(max_length=45, blank=True, null=True) + astro_coord_system = models.CharField(max_length=45, blank=True, null=True) + jd_send = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True) + jd_received = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True) + trig_id = models.IntegerField(blank=True, null=True) + error_radius = models.FloatField(max_length=45, blank=True, null=True) + defly_not_grb = models.BooleanField(default=False) + editor = models.CharField(max_length=45, blank=True, null=True) + soln_status = models.CharField(max_length=45, blank=True, null=True) + pkt_ser_num = models.IntegerField(blank=True, null=True) + + class Meta: + managed = True + db_table = 'alert' + + def __str__(self): + return str(self.trig_id) + + def request_name(self): + return self.__str__() + + request_name.short_description = "Name" + + + class Command(models.Model): """ - | id | sender | receiver | name | validity_duration_sec (default=60) | sender_deposit_time | receiver_read_time + | id | sender | recipient | name | validity_duration (default=60) | s_deposit_time | r_read_time """ # -------------- Command CONSTANTS -------------- @@ -254,18 +358,18 @@ class Command(models.Model): #sender = models.CharField(max_length=50, blank=True, null=True, unique=True) sender = models.CharField(max_length=50, help_text='sender agent name') - receiver = models.CharField(max_length=50, help_text='receiver agent name') + recipient = models.CharField(max_length=50, help_text='recipient agent name') name = models.CharField(max_length=400, help_text='command name') - validity_duration_sec = models.PositiveIntegerField(default=COMMANDS_VALIDITY_DURATION_SEC_DEFAULT) + validity_duration = models.PositiveIntegerField('(in sec)', default=COMMANDS_VALIDITY_DURATION_SEC_DEFAULT) # Automatically set at table line creation (line created by the sender) - sender_deposit_time = models.DateTimeField(blank=True, null=True, auto_now_add=True) - # Set by the receiver : + s_deposit_time = models.DateTimeField(blank=True, null=True, auto_now_add=True) + # Set by the recipient : # - at reading time - receiver_read_time = models.DateTimeField(null=True) + r_read_time = models.DateTimeField(null=True) # - after execution - receiver_processed_time = models.DateTimeField(null=True) - receiver_status_code = models.CharField(choices = CMD_STATUS_CODES, default=CMD_STATUS_CODES.CMD_PENDING, max_length=20) - #receiver_status_code = models.IntegerField(choices=CMD_STATUS_CODES, default=RSCODE_PENDING) + r_processed_time = models.DateTimeField(null=True) + r_status_code = models.CharField(choices = CMD_STATUS_CODES, default=CMD_STATUS_CODES.CMD_PENDING, max_length=20) + #r_status_code = models.IntegerField(choices=CMD_STATUS_CODES, default=RSCODE_PENDING) # TODO: maybe à mettre au format json (key:value) result = models.CharField(max_length=400, blank=True) @@ -281,7 +385,7 @@ class Command(models.Model): """ @classmethod def send(cls, cmd:Command): - cls.objects.create(sender=cmd.name, receiver=cmd.receiver, name=cmd.name) + cls.objects.create(sender=cmd.name, recipient=cmd.recipient, name=cmd.name) """ @classmethod def send_command(cls, from_agent, to_agent, cmd_name, cmd_args=None): @@ -289,8 +393,8 @@ class Command(models.Model): ex: send("AgentA",“AgentB”,"EVAL”,“3+4”) """ if cmd_args: cmd_name += ' '+cmd_args - #Command.objects.create(sender=self.name, receiver=receiver_agent, name=cmd_name) - cmd = cls(sender=from_agent, receiver=to_agent, name=cmd_name) + #Command.objects.create(sender=self.name, recipient=r_agent, name=cmd_name) + cmd = cls(sender=from_agent, recipient=to_agent, name=cmd_name) cmd.send() #cmd.set_as_pending() #cmd.save() @@ -305,11 +409,11 @@ class Command(models.Model): print("Delete (false) 'running' command if exists:") running_commands = cls.objects.filter( # only commands for agent agent_name - receiver = agent_name, + recipient = agent_name, # only running commands - receiver_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING, + r_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING, # only not expired commands - #sender_deposit_time__gte = cls.get_peremption_date_from_now(), + #s_deposit_time__gte = cls.get_peremption_date_from_now(), ) if running_commands: Command.show_commands(running_commands) @@ -331,11 +435,11 @@ class Command(models.Model): #print("now_minus_2sec", now_minus_2sec) pending_commands = cls.objects.filter( # only commands for agent agent_name - receiver = agent_name, + recipient = agent_name, # only running commands - receiver_status_code = cls.CMD_STATUS_CODES.CMD_PENDING, + r_status_code = cls.CMD_STATUS_CODES.CMD_PENDING, # except very recent commands : take only commands that are more than 2 sec old - sender_deposit_time__lt = now_minus_2sec + s_deposit_time__lt = now_minus_2sec ) if pending_commands: Command.show_commands(pending_commands) @@ -348,16 +452,16 @@ class Command(models.Model): return cls.objects.filter( # only pending commands # but also including the currently running command - Q(receiver_status_code = cls.CMD_STATUS_CODES.CMD_PENDING) | Q(receiver_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING), + Q(r_status_code = cls.CMD_STATUS_CODES.CMD_PENDING) | Q(r_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING), # only commands for agent agent_name - receiver = agent_name, + recipient = agent_name, # only not expired commands - #sender_deposit_time__gte = cls.get_peremption_date_from_now(), - ).order_by("sender_deposit_time") + #s_deposit_time__gte = cls.get_peremption_date_from_now(), + ).order_by("s_deposit_time") @classmethod def get_commands_sent_to_agent(cls, agent_name): - return cls.objects.filter(receiver=agent_name) + return cls.objects.filter(recipient=agent_name) @classmethod def get_commands_sent_by_agent(cls, agent_name): @@ -367,7 +471,7 @@ class Command(models.Model): def get_last_N_commands_sent_to_agent(cls, agent_name, N): #filter(since=since) #return cls.objects.all()[:nb_cmds] - #commands = cls.objects.filter(receiver = agent_name).order_by('-id')[:N] + #commands = cls.objects.filter(recipient = agent_name).order_by('-id')[:N] commands = cls.get_commands_sent_to_agent(agent_name).order_by('-id')[:N] return list(reversed(commands)) @@ -375,7 +479,7 @@ class Command(models.Model): def get_last_N_commands_sent_by_agent(cls, agent_name, N): #filter(since=since) #return cls.objects.all()[:nb_cmds] - #commands = cls.objects.filter(receiver = agent_name).order_by('-id')[:N] + #commands = cls.objects.filter(recipient = agent_name).order_by('-id')[:N] commands = cls.get_commands_sent_by_agent(agent_name).order_by('-id')[:N] return list(reversed(commands)) @@ -392,11 +496,11 @@ class Command(models.Model): #print("peremption date", COMMAND_PEREMPTION_DATE_FROM_NOW) old_commands = cls.objects.filter( # only commands for agent agent_name - receiver = agent_name, + recipient = agent_name, # only expired commands - sender_deposit_time__lt = cls.get_peremption_date_from_now(), + s_deposit_time__lt = cls.get_peremption_date_from_now(), ).exclude( - receiver_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING + r_status_code = cls.CMD_STATUS_CODES.CMD_RUNNING ) if old_commands.exists(): print("Found old commands to delete:") @@ -419,7 +523,7 @@ class Command(models.Model): # -------------- Command INSTANCE METHODS -------------- def __str__(self): - return (f"Commmand '{self.name}' ({self.receiver_status_code}) sent by agent {self.sender} to agent {self.receiver} at {self.sender_deposit_time}") + return (f"Commmand '{self.name}' ({self.r_status_code}) sent by agent {self.sender} to agent {self.recipient} at {self.s_deposit_time}") # --- BOOLEAN (test) functions --- @@ -439,30 +543,30 @@ class Command(models.Model): "CMD_OUTOFDATE" # cde périmée def is_read(self): - return self.receiver_read_time is not None + return self.r_read_time is not None def is_pending(self): - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_PENDING + return self.r_status_code == self.CMD_STATUS_CODES.CMD_PENDING def is_running(self): - #return (datetime.utcnow() - self.sender_deposit_time) > timedelta(seconds = self.validity_duration_sec) - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_RUNNING + #return (datetime.utcnow() - self.s_deposit_time) > timedelta(seconds = self.validity_duration) + return self.r_status_code == self.CMD_STATUS_CODES.CMD_RUNNING def is_executed(self): - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_EXECUTED + return self.r_status_code == self.CMD_STATUS_CODES.CMD_EXECUTED def is_skipped(self): - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_SKIPPED + return self.r_status_code == self.CMD_STATUS_CODES.CMD_SKIPPED def is_killed(self): - return self.receiver_status_code == self.CMD_STATUS_CODES.CMD_KILLED + return self.r_status_code == self.CMD_STATUS_CODES.CMD_KILLED def is_expired(self): - #return (datetime.utcnow() - self.sender_deposit_time) > timedelta(seconds = self.validity_duration_sec) - return (datetime.utcnow().astimezone() - self.sender_deposit_time) > timedelta(seconds = self.validity_duration_sec) + #return (datetime.utcnow() - self.s_deposit_time) > timedelta(seconds = self.validity_duration) + return (datetime.utcnow().astimezone() - self.s_deposit_time) > timedelta(seconds = self.validity_duration) """ - elapsed_time = cmd.receiver_read_time - cmd.sender_deposit_time - max_time = timedelta(seconds = cmd.validity_duration_sec) + elapsed_time = cmd.r_read_time - cmd.s_deposit_time + max_time = timedelta(seconds = cmd.validity_duration) print(f"Elapsed time is {elapsed_time}, (max is {max_time})") if elapsed_time > max_time: """ @@ -481,21 +585,21 @@ class Command(models.Model): self.save() def set_read_time(self): - self.receiver_read_time = datetime.utcnow().astimezone() + self.r_read_time = datetime.utcnow().astimezone() # Optimization: update only 1 field - self.save(update_fields=["receiver_read_time"]) + self.save(update_fields=["r_read_time"]) def set_as_processed(self): print(f"- Set command {self.name} as processed") #print(self) - self.receiver_status_code = self.CMD_STATUS_CODES.CMD_EXECUTED - self.receiver_processed_time = datetime.utcnow().astimezone() + self.r_status_code = self.CMD_STATUS_CODES.CMD_EXECUTED + self.r_processed_time = datetime.utcnow().astimezone() self.save() # Optimization: update the related fields, but does not work, why ? - ##self.save(update_fields=["receiver_status_code", "receiver_processed_time"]) + ##self.save(update_fields=["r_status_code", "r_processed_time"]) def set_as_outofdate(self): - print(f"- Set this command as expired (older than its validity duration of {self.validity_duration_sec}s): {self}") + print(f"- Set this command as expired (older than its validity duration of {self.validity_duration}s): {self}") self.set_status_to(self.CMD_STATUS_CODES.CMD_OUTOFDATE) def set_as_pending(self): @@ -518,112 +622,10 @@ class Command(models.Model): ''' def set_status_to(self, status:str): - self.receiver_status_code = status + self.r_status_code = status self.save() # Optimization, but does not work, why ?... - ##self.save(update_fields=["receiver_status_code"]) - - -class AgentSurvey(models.Model): - """ - | id | name | created | updated | validity_duration_sec (default=1mn) | mode (active/idle) | status (launch/init/loop/exit/...) | - """ - - # Statuses - #STATUSES = Choices('new', 'verified', 'published') - STATUS_LAUNCH = "LAUNCHED" - STATUS_INIT = "INITIALIZING" - STATUS_MAIN_LOOP = "IN_MAIN_LOOP" - STATUS_PROCESS_LOOP = "IN_PROCESS_LOOP" - STATUS_EXIT = "EXITING" - - # Modes - MODE_ACTIVE = "ACTIVE" - MODE_IDLE = "IDLE" - - MODE_CHOICES = ( - (MODE_ACTIVE, 'Active mode'), - (MODE_IDLE, 'Idle mode'), - ) - - STATUS_CHOICES = ( - (STATUS_LAUNCH, "LAUNCHED"), - (STATUS_INIT, "INITIALIZING"), - (STATUS_MAIN_LOOP, "IN_MAIN_LOOP"), - (STATUS_PROCESS_LOOP, "IN_PROCESS_LOOP"), - (STATUS_EXIT, "EXITING"), - ) - - name = models.CharField(max_length=50, unique=True) - #name = models.CharField(max_length=50, blank=True, null=True, unique=True) - #created = models.DateTimeField(blank=True, null=True, auto_now_add=True) - created = models.DateTimeField(blank=True, null=True, auto_now_add=True) - updated = models.DateTimeField(blank=True, null=True, auto_now=True) - validity_duration_sec = models.PositiveIntegerField(default=90) - #validity_duration_sec = models.DurationField(default=90) - mode = models.CharField('agent mode', max_length=15, blank=True, choices=MODE_CHOICES) - status = models.CharField(max_length=15, blank=True, choices=STATUS_CHOICES) - - class Meta: - managed = True - db_table = 'agent_survey' - #verbose_name = "agent survey" - #verbose_name_plural = "agents survey" - - def __str__(self): - return (f"Agent {self.name} at {self.updated} in mode {self.mode} and status {self.status}") - - -class Album(models.Model): - sequence = models.ForeignKey( - 'Sequence', on_delete=models.CASCADE, related_name="albums") - detector = models.ForeignKey( - 'Detector', models.DO_NOTHING, related_name="albums", blank=True, null=True) - name = models.CharField(max_length=45, blank=True, null=True) - desc = models.TextField(blank=True, null=True) - created = models.DateTimeField(blank=True, null=True, auto_now_add=True) - updated = models.DateTimeField(blank=True, null=True, auto_now=True) - complete = models.BooleanField(default=False) - - class Meta: - managed = True - db_table = 'album' - #verbose_name_plural = "Albums" - - def __str__(self): - return (str(self.name)) - - -class Alert(Request): - request = models.OneToOneField('Request', on_delete=models.CASCADE, default='', parent_link=True) - strategyobs = models.ForeignKey( - 'StrategyObs', models.DO_NOTHING, related_name="alerts", blank=True, null=True) - voevent_file = models.CharField(max_length=45, blank=True, null=True) - author = models.CharField(max_length=45, blank=True, null=True) - burst_jd = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True) - burst_ra = models.FloatField(max_length=45, blank=True, null=True) - burst_dec = models.FloatField(max_length=45, blank=True, null=True) - astro_coord_system = models.CharField(max_length=45, blank=True, null=True) - jd_send = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True) - jd_received = models.DecimalField(max_digits=15, decimal_places=8, blank=True, null=True) - trig_id = models.IntegerField(blank=True, null=True) - error_radius = models.FloatField(max_length=45, blank=True, null=True) - defly_not_grb = models.BooleanField(default=False) - editor = models.CharField(max_length=45, blank=True, null=True) - soln_status = models.CharField(max_length=45, blank=True, null=True) - pkt_ser_num = models.IntegerField(blank=True, null=True) - - class Meta: - managed = True - db_table = 'alert' - - def __str__(self): - return str(self.trig_id) - - def request_name(self): - return self.__str__() - - request_name.short_description = "Name" + ##self.save(update_fields=["r_status_code"]) -- libgit2 0.21.2