Commit 573eeae666016117994bf272ef844894c84bd5b9
1 parent
ff76bcca
Exists in
dev
Agent ne depend plus de AgentDevice, et TEST ok avec self pour envoyer commandes a soi meme
Showing
2 changed files
with
87 additions
and
21 deletions
Show diff stats
src/core/pyros_django/agent/Agent.py
... | ... | @@ -302,13 +302,13 @@ class Agent: |
302 | 302 | #"set_state", |
303 | 303 | ] |
304 | 304 | |
305 | + # --- FOR TEST ONLY --- | |
306 | + | |
305 | 307 | # Maximum duration of this agent (only for SIMULATION mode) |
306 | 308 | # If set to None, it will never exit except if asked (or CTRL-C) |
307 | 309 | # If set to 20, it will exit after 20s |
308 | 310 | TEST_MAX_DURATION_SEC = None |
309 | 311 | #TEST_MAX_DURATION_SEC = 30 |
310 | - | |
311 | - # FOR TEST ONLY | |
312 | 312 | # Run this agent in simulator mode |
313 | 313 | TEST_MODE = True |
314 | 314 | WITH_SIMULATOR = False |
... | ... | @@ -316,12 +316,29 @@ class Agent: |
316 | 316 | TEST_WITH_FINAL_TEST = False |
317 | 317 | # Who should I send commands to ? |
318 | 318 | TEST_COMMANDS_DEST = "myself" |
319 | - # Default scenario to be executed | |
319 | + | |
320 | + # (EP 2022/06) Default scenario to be executed (only in TEST mode) | |
321 | + # | |
322 | + # List of commands to be sent by this agent to other agents ("self" means himself) | |
323 | + # | |
324 | + # Command format is : | |
325 | + # "[Recipient] Command [Args]" | |
326 | + # with : | |
327 | + # - [Recipient] optional, the name of the Agent the command is to be sent to (use "self" to mean himself) | |
328 | + # - Command, the command name | |
329 | + # - [Args] optional, the list of command arguments, separated by blanks : arg1 arg2 arg3 ... | |
330 | + # | |
331 | + # Ex : | |
332 | + # - "AgentScheduler set_state ATTENTIVE" => means to send the command "set_state ATTENTIVE" to the agent AgentScheduler | |
333 | + # - "AgentX set_state ATTENTIVE" => means to send the command "set_state ATTENTIVE" to the agent AgentX | |
334 | + # - "self set_state ATTENTIVE" => means to send the command "set_state ATTENTIVE" to MYSELF | |
335 | + # - "self do_restart_loop" => means to send the command "do_restart_loop" to MYSELF (no args) | |
336 | + # | |
320 | 337 | #TEST_COMMANDS = iter([ |
321 | 338 | TEST_COMMANDS_LIST = [ |
322 | 339 | "Agent set_state ATTENTIVE", |
323 | - "Agent set_state ROUTINE", | |
324 | - "Agent set_state IDLE", | |
340 | + "self set_state ROUTINE", | |
341 | + "self set_state IDLE", | |
325 | 342 | |
326 | 343 | ''' |
327 | 344 | # specific0 not_executed_because_idle |
... | ... | @@ -1656,7 +1673,7 @@ class Agent: |
1656 | 1673 | cmd.set_as_running() |
1657 | 1674 | |
1658 | 1675 | log.info("(Agent level GENERAL CMD)") |
1659 | - _,cmd_name,cmd_args = cmd.get_full_name_parts() | |
1676 | + cmd_name,cmd_args = cmd.get_name_and_args() | |
1660 | 1677 | #cmd_name, cmd_args = cmd.tokenize() |
1661 | 1678 | #if cmd.name == "set_state:active": |
1662 | 1679 | #elif cmd.name == "set_state:idle": |
... | ... | @@ -1877,11 +1894,13 @@ class Agent: |
1877 | 1894 | if cmd_full_name is None: return None |
1878 | 1895 | if ' ' not in cmd_full_name: raise Exception('Command is malformed:', cmd_full_name) |
1879 | 1896 | agent_recipient,cmd_name = cmd_full_name.split(' ', 1) |
1897 | + # Command is to be sent to myself ? | |
1898 | + if agent_recipient == 'self': agent_recipient = self.name | |
1880 | 1899 | ##recipient_agent = self.name if self.TEST_COMMANDS_DEST=="myself" else self.TEST_COMMANDS_DEST |
1881 | 1900 | #return Command(sender=self.name, recipient=recipient_agent, name=cmd_name) |
1882 | 1901 | cmd = self.create_cmd_for(agent_recipient, cmd_name) |
1883 | 1902 | # If no cmd created (because of error, bad AgentDevice name), call again this method for next cmd |
1884 | - if cmd is None: return self._TEST_get_next_command_to_send() | |
1903 | + #if cmd is None: return self._TEST_get_next_command_to_send() | |
1885 | 1904 | return cmd |
1886 | 1905 | |
1887 | 1906 | """ | ... | ... |
src/core/pyros_django/common/models.py
... | ... | @@ -8,7 +8,7 @@ from datetime import datetime, timedelta, date |
8 | 8 | from dateutil.relativedelta import relativedelta |
9 | 9 | import os |
10 | 10 | import sys |
11 | -from typing import List | |
11 | +from typing import List, Tuple | |
12 | 12 | from django.core.validators import MaxValueValidator, MinValueValidator |
13 | 13 | |
14 | 14 | # DJANGO imports |
... | ... | @@ -423,8 +423,14 @@ class Alert(Request): |
423 | 423 | |
424 | 424 | |
425 | 425 | class AgentCmd(models.Model): |
426 | - | |
427 | 426 | """ |
427 | + Command sent to an Agent | |
428 | + | |
429 | + Can be either : | |
430 | + - an "agent level" (general or specific) command | |
431 | + OR | |
432 | + - a "device level" command | |
433 | + | |
428 | 434 | | id | sender | recipient | name | validity_duration (default=60) | s_deposit_time | r_read_time |
429 | 435 | |
430 | 436 | See doc/models_Command_state_diag.pu for PlantUML state diagram |
... | ... | @@ -459,11 +465,28 @@ class AgentCmd(models.Model): |
459 | 465 | "CMD_OUTOFDATE" # cde pรฉrimรฉe |
460 | 466 | ) |
461 | 467 | _AGENT_GENERAL_COMMANDS = [ |
462 | - #"do_eval", "set_state:idle", "set_state:active", | |
468 | + # DO commands | |
469 | + # - Evaluate the expression given (ex: do_eval 4+3) | |
463 | 470 | "do_eval", |
471 | + # GET commands | |
472 | + # - Get agent current state (idle, routine, attentive) | |
473 | + "get_state", | |
474 | + # SET commands | |
475 | + # - Set agent current state (idle, routine, attentive) | |
464 | 476 | "set_state", |
465 | 477 | # Commands executed in priority (even if other pending commands exist) |
466 | - "do_flush_commands", "do_abort", "do_exit", "do_restart_init" | |
478 | + # - Remove all your pending commands | |
479 | + "do_flush_commands", | |
480 | + # - Abort the command you are currently running | |
481 | + "do_abort_current_command", | |
482 | + # - do_abort_current_command and then stop immediately | |
483 | + "do_abort", | |
484 | + # - finish your current command and then make a normal clean stop | |
485 | + "do_exit", | |
486 | + # - restart your global loop (starting with init()) | |
487 | + "do_restart_loop", | |
488 | + # - restart completely an agent (only AgentSST can do this) : do_exit + start again | |
489 | + "do_restart_agent", | |
467 | 490 | ] |
468 | 491 | #COMMANDS_PEREMPTION_HOURS = 48 |
469 | 492 | COMMANDS_PEREMPTION_HOURS = 60/60 |
... | ... | @@ -696,7 +719,7 @@ class AgentCmd(models.Model): |
696 | 719 | return (f"Commmand '{self.full_name}' ({self.state}) sent to agent {self.recipient}{cmd_sent_time} [by agent {self.sender}]") |
697 | 720 | |
698 | 721 | @property |
699 | - def device_command(self): | |
722 | + def device_command(self) -> DeviceCmd : | |
700 | 723 | if not self._device_command: |
701 | 724 | self._device_command = DeviceCmd(self.full_name) |
702 | 725 | #dc = self._device_command |
... | ... | @@ -713,18 +736,42 @@ class AgentCmd(models.Model): |
713 | 736 | return cmd_name_and_args |
714 | 737 | ''' |
715 | 738 | |
716 | - def get_full_name_parts(self): | |
717 | - return self.device_command.get_full_name_parts() | |
718 | - ''' | |
719 | - cmd_name = self.full_name | |
720 | - cmd_type = None | |
739 | + | |
740 | + #def get_name_and_args(self) -> list(str, str) : | |
741 | + def get_name_and_args(self) -> list : | |
742 | + ''' Return command name and args if exist ''' | |
743 | + # By default, no args | |
721 | 744 | cmd_args = None |
722 | - if '.' in cmd_name: | |
723 | - cmd_type, cmd_name = cmd_name.split('.') | |
745 | + cmd_name = self.full_name | |
724 | 746 | if ' ' in cmd_name: |
725 | 747 | cmd_name, *cmd_args = cmd_name.split(' ') |
726 | - return cmd_type, cmd_name, cmd_args | |
727 | - ''' | |
748 | + print(cmd_name, cmd_args) | |
749 | + return cmd_name, cmd_args | |
750 | + | |
751 | + | |
752 | + #def get_full_name_parts(self) -> tuple(str, str, str) : | |
753 | + def get_full_name_parts(self) -> list : | |
754 | + ''' Return command device type, name, and args from any command type (agent or device level) ''' | |
755 | + | |
756 | + # No device type by default for an Agent command | |
757 | + # cmd_type ? | |
758 | + dev_type = None | |
759 | + | |
760 | + # By default, no args | |
761 | + cmd_args = None | |
762 | + | |
763 | + cmd_name = self.full_name | |
764 | + | |
765 | + # Device command with device component type (dev_type) | |
766 | + if '.' in cmd_name: | |
767 | + return self.device_command.get_full_name_parts() | |
768 | + | |
769 | + # Simple command with args (no dev_type) | |
770 | + if ' ' in cmd_name: | |
771 | + cmd_name, *cmd_args = self.get_name_and_args() | |
772 | + | |
773 | + return dev_type, cmd_name, cmd_args | |
774 | + | |
728 | 775 | |
729 | 776 | @property |
730 | 777 | def name(self): | ... | ... |