Commit da405f5ba35acfe8fc051bbb6a6f2105d1eda3ad
1 parent
ae07b789
Exists in
dev
get_all_cmds remplace get_specific_cmds
Showing
6 changed files
with
212 additions
and
125 deletions
Show diff stats
CHANGELOG
1 | +08-11-2022 (EP): v0.6.8.0 | |
2 | + - get_all_cmds() remplace get_specific_cmds() et renvoie la liste de TOUTES les commandes : générales ET spécifiques | |
3 | + - Paramètres des commandes générales vérifiés via assertion, si erreur = Exception | |
4 | + | |
1 | 5 | 07-11-2022 (EP): v0.6.7.4 |
2 | 6 | - Allow commands to be sent manually to an agent even if in TEST mode, without disturbing it |
3 | 7 | - Bugfix result = "0" (=false) => now shown | ... | ... |
VERSION
privatedev/plugin/agent/AgentBasic.py
... | ... | @@ -86,12 +86,9 @@ class AgentBasic(Agent): |
86 | 86 | # ---------------------------------------------------- |
87 | 87 | |
88 | 88 | |
89 | - # - Error case 2 - Unimplemented command (in agent specific commands list) | |
90 | - | |
91 | - | |
92 | 89 | # - Error case 1 - CMD_INVALID |
93 | 90 | # a) Misnamed commands |
94 | - (True, "self cmd_misnamed_and_declared", 200, "Command misnamed, must start with do_, get_, or set_", Agent.CMD_STATUS.CMD_INVALID), | |
91 | + (COMMIT_ONLY, "self cmd_misnamed_and_declared", 200, "Command misnamed, must start with do_, get_, or set_", Agent.CMD_STATUS.CMD_INVALID), | |
95 | 92 | (COMMIT_ONLY, "self cmd_misnamed_and_undeclared", 200, None, Agent.CMD_STATUS.CMD_INVALID), |
96 | 93 | # b) Unknwon command |
97 | 94 | ##FIXME: ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_UNKNOWN), |
... | ... | @@ -105,9 +102,12 @@ class AgentBasic(Agent): |
105 | 102 | (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, None, Agent.CMD_STATUS.CMD_INVALID), |
106 | 103 | # - bad type |
107 | 104 | (True, "self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_INVALID), |
105 | + (True, "self set_mode unknown_mode", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
106 | + (True, "self do_eval bad_arg", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
108 | 107 | # - OK |
109 | 108 | #("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), |
110 | 109 | |
110 | + # - Error case 2 - Unimplemented command (in agent specific commands list) | |
111 | 111 | # - Error case 3 - CMD_UNIMPLEMENTED |
112 | 112 | (True, "self do_cmd_unimplemented_and_declared", 200, None, Agent.CMD_STATUS.CMD_UNIMPLEMENTED), |
113 | 113 | |
... | ... | @@ -120,19 +120,21 @@ class AgentBasic(Agent): |
120 | 120 | (COMMIT_ONLY, "self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), |
121 | 121 | (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), |
122 | 122 | # b) Back to mode ATTENTIVE, SPECIFIC commands should be executed |
123 | - (COMMIT_ONLY, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
123 | + (True, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
124 | 124 | (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), |
125 | 125 | |
126 | + | |
126 | 127 | # ---------------------------------------------------- |
127 | 128 | # ------ B - ERROR CASES - from RUNNING status ------- |
128 | 129 | # ---------------------------------------------------- |
129 | - | |
130 | 130 | |
131 | 131 | (True, "self do_cmd_raising_some_exception", 200, |
132 | 132 | #"EXCEPTION on command do_cmd_raising_some_exception: StopIteration", |
133 | 133 | "EXCEPTION on command do_cmd_raising_some_exception: StopIteration: Some exception was raised", |
134 | 134 | Agent.CMD_STATUS.CMD_EXEC_ERROR), |
135 | 135 | #(True, "self do_cmd_raising_some_exception", 200, "EXCEPTION on command do_cmd_raising_some_exception: Error during Execution", Agent.CMD_STATUS.CMD_EXEC_ERROR), |
136 | + | |
137 | + | |
136 | 138 | # ------------------------------ |
137 | 139 | # ------ C - NORMAL CASES ------- |
138 | 140 | # ------------------------------ | ... | ... |
src/core/pyros_django/agent/Agent.py
... | ... | @@ -42,7 +42,7 @@ and execute them on reception at each iteration : |
42 | 42 | # For cmd parsing |
43 | 43 | from array import array |
44 | 44 | from datetime import datetime |
45 | -from typing import List, Tuple, Union, Any, Optional | |
45 | +from typing import List, Tuple, Union, Any, Optional, Literal | |
46 | 46 | import ast |
47 | 47 | from inspect import signature |
48 | 48 | |
... | ... | @@ -183,6 +183,15 @@ from device_controller.abstract_component.device_controller import ( |
183 | 183 | |
184 | 184 | |
185 | 185 | |
186 | +from enum import Enum | |
187 | +class Season(Enum): | |
188 | + SPRING = 1 | |
189 | + SUMMER = 2 | |
190 | + AUTUMN = 3 | |
191 | + WINTER = 4 | |
192 | + | |
193 | + | |
194 | + | |
186 | 195 | ### |
187 | 196 | # ================================================================= |
188 | 197 | # GENERAL MODULE CONSTANT & FUNCTIONS DEFINITIONS |
... | ... | @@ -1091,6 +1100,9 @@ class Agent: |
1091 | 1100 | # SIMU |
1092 | 1101 | #self.send_cmd_to("AgentScheduler", "do_replan") |
1093 | 1102 | |
1103 | + #print("general cmds:", self.get_general_cmds()) | |
1104 | + ##print("all cmds:", self.get_all_cmds()) | |
1105 | + | |
1094 | 1106 | # ROUTINE BEFORE (only if not IDLE) |
1095 | 1107 | #if not self.IS_IDLE(): |
1096 | 1108 | self.__routine_process_before() |
... | ... | @@ -1210,7 +1222,7 @@ class Agent: |
1210 | 1222 | commands = AgentCmd.get_pending_and_running_commands_for_agent(self.name) |
1211 | 1223 | if not commands.exists(): return None |
1212 | 1224 | for cmd in commands: |
1213 | - #if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): break | |
1225 | + #if cmd.name in ("do_exit", "do_abort", "do_flush_pending_commands"): break | |
1214 | 1226 | #if cmd.name in ("do_exit", "do_abort"): break |
1215 | 1227 | if cmd.is_agent_general_priority_cmd(): |
1216 | 1228 | # If prio cmd but irrelevant => skip it |
... | ... | @@ -1284,7 +1296,7 @@ class Agent: |
1284 | 1296 | #commands = AgentCmd.get_commands_sent_to_agent(self.name) |
1285 | 1297 | commands = AgentCmd.get_pending_and_running_commands_for_agent(self.name) |
1286 | 1298 | AgentCmd.show_commands(commands, True) |
1287 | - ##self.do_flush_commands() | |
1299 | + ##self.do_flush_pending_commands() | |
1288 | 1300 | |
1289 | 1301 | # Only if in TEST mode |
1290 | 1302 | #if self.TEST_MODE and self.TEST_WITH_FINAL_TEST and self.TEST_COMMANDS_DEST == "myself": self.simulator_test_results() |
... | ... | @@ -1450,7 +1462,7 @@ class Agent: |
1450 | 1462 | return #cmd |
1451 | 1463 | |
1452 | 1464 | # CASE 1 - AGENT GENERAL command |
1453 | - # (DO_RESTART, DO_EXIST, DO_ABORT, DO_ABORT_COMMAND, DO_FLUSH_COMMANDS, ...) | |
1465 | + # (DO_RESTART, DO_EXIST, DO_ABORT, DO_ABORT_COMMAND, do_flush_pending_commands, ...) | |
1454 | 1466 | # This processing can set DO_MAIN_LOOP and DO_RESTART_LOOP to False |
1455 | 1467 | if self.is_agent_general_cmd(cmd): |
1456 | 1468 | try: |
... | ... | @@ -1628,62 +1640,6 @@ class Agent: |
1628 | 1640 | self.waitfor(nbsec) |
1629 | 1641 | |
1630 | 1642 | |
1631 | - def get_specific_cmds(self)->str: | |
1632 | - specific_commands = "" | |
1633 | - # For each command | |
1634 | - for command_tuple in self._AGENT_SPECIFIC_COMMANDS: | |
1635 | - | |
1636 | - cmd_name = command_tuple[0] | |
1637 | - #print(cmd_name) | |
1638 | - specific_commands += cmd_name | |
1639 | - | |
1640 | - # 1) Error case 1 - Badly named command (not get, set, do) (implemented or not) | |
1641 | - if not AgentCmd.is_generic(cmd_name): | |
1642 | - specific_commands += '(I);' | |
1643 | - continue | |
1644 | - | |
1645 | - # 2) Error case 2 - Well named command (get, set, do) but not yet implemented | |
1646 | - try: | |
1647 | - f = getattr(self, cmd_name) | |
1648 | - # Exception if exists an unimplemented command | |
1649 | - except AttributeError: | |
1650 | - # Tag this command as UNIMPLEMENTED (U) => 'cmd_name(U)' | |
1651 | - #raise CmdExceptionUnimplemented(cmd_name) from None | |
1652 | - specific_commands += '(U);' | |
1653 | - # next cmd | |
1654 | - continue | |
1655 | - | |
1656 | - # 3) Normal case : well named command and implemented | |
1657 | - specific_commands += "(" | |
1658 | - args = signature(f) | |
1659 | - #specific_commands += str(args) | |
1660 | - #print(specific_commands) | |
1661 | - #print(args.parameters) | |
1662 | - for arg in args.parameters.values(): | |
1663 | - arg_type = arg.annotation.__name__ if isinstance(arg.annotation,type) else str(arg.annotation) | |
1664 | - specific_commands += arg.name+":"+arg_type+"," | |
1665 | - #print("name, annot:", arg.name, arg.annotation) | |
1666 | - #print("annot.nam e:", arg.annotation.__name__) | |
1667 | - #print(type(arg.annotation)) | |
1668 | - ''' | |
1669 | - for arg in args.parameters: | |
1670 | - print(arg) | |
1671 | - arg = args.parameters[arg] | |
1672 | - #print(arg) | |
1673 | - #print("name, annot:", arg.name, arg.annotation) | |
1674 | - #print("annot.name:", arg.annotation.__name__) | |
1675 | - #print(type(arg.annotation)) | |
1676 | - arg_type = arg.annotation.__name__ if isinstance(arg.annotation,type) else str(arg.annotation) | |
1677 | - specific_commands += arg.name+":"+arg_type+"," | |
1678 | - ''' | |
1679 | - # specific_commands += str(args) | |
1680 | - if args.parameters: specific_commands = specific_commands[:-1] | |
1681 | - specific_commands += ")" | |
1682 | - specific_commands += ";" | |
1683 | - | |
1684 | - if specific_commands: specific_commands = specific_commands[0:-1] | |
1685 | - #print(specific_commands) | |
1686 | - return specific_commands | |
1687 | 1643 | |
1688 | 1644 | # |
1689 | 1645 | # MODE & STATUS |
... | ... | @@ -1739,7 +1695,8 @@ class Agent: |
1739 | 1695 | def IS_ATTENTIVE(self): return self.IS_MODE_ATTENTIVE() |
1740 | 1696 | |
1741 | 1697 | # - SET |
1742 | - def __set_mode(self, mode:str): | |
1698 | + #def __set_mode(self, mode:str): | |
1699 | + def __set_mode(self, mode:AgentSurvey.MODE_CHOICES): | |
1743 | 1700 | #self.printd(f"Switching from mode {self.__mode} to mode {mode}") |
1744 | 1701 | log.info(f"[NEW MODE {mode}]") |
1745 | 1702 | self.__mode = mode |
... | ... | @@ -1747,24 +1704,16 @@ class Agent: |
1747 | 1704 | # Public method because can be called from outside like this : agent.set_mode_idle() |
1748 | 1705 | def set_mode_idle(self): |
1749 | 1706 | self.__set_mode(AgentSurvey.MODE_CHOICES.IDLE) |
1750 | - # @deprecated | |
1751 | - def set_idle(self): | |
1752 | - self.set_mode_idle() | |
1753 | 1707 | |
1754 | 1708 | # Public method because can be called from outside like this : agent.set_mode_routine() |
1755 | 1709 | def set_mode_routine(self): |
1756 | 1710 | self.__set_mode(AgentSurvey.MODE_CHOICES.ROUTINE) |
1757 | - # @deprecated | |
1758 | - def set_routine(self): | |
1759 | - self.set_mode_routine() | |
1760 | 1711 | |
1761 | 1712 | # Public method because can be called from outside like this : agent.set_mode_attentive() |
1762 | 1713 | def set_mode_attentive(self): |
1763 | 1714 | #self._set_mode(AgentSurvey.MODE_ATTENTIVE) |
1764 | 1715 | self.__set_mode(AgentSurvey.MODE_CHOICES.ATTENTIVE) |
1765 | - # @deprecated | |
1766 | - def set_attentive(self): | |
1767 | - self.set_mode_attentive() | |
1716 | + | |
1768 | 1717 | |
1769 | 1718 | |
1770 | 1719 | |
... | ... | @@ -2019,7 +1968,7 @@ class Agent: |
2019 | 1968 | ) |
2020 | 1969 | ''' |
2021 | 1970 | |
2022 | - def get_my_received_pending_commands(self) -> QuerySet: | |
1971 | + def get_received_pending_commands(self) -> QuerySet: | |
2023 | 1972 | return AgentCmd.get_pending_and_running_commands_for_agent(self.name) |
2024 | 1973 | |
2025 | 1974 | def __get_next_received_cmd_if_exists(self) -> Optional[AgentCmd]: |
... | ... | @@ -2039,7 +1988,7 @@ class Agent: |
2039 | 1988 | # but there might be a risk |
2040 | 1989 | # that a command status is modified while we are reading... |
2041 | 1990 | with transaction.atomic(): |
2042 | - self.__pending_commands = self.get_my_received_pending_commands() | |
1991 | + self.__pending_commands = self.get_received_pending_commands() | |
2043 | 1992 | commands = self.__pending_commands |
2044 | 1993 | if not commands.exists(): |
2045 | 1994 | log.info("<None>") |
... | ... | @@ -2057,7 +2006,7 @@ class Agent: |
2057 | 2006 | # and |
2058 | 2007 | # - GET a PRIORITY command if exists in the list (even at the very end ; must be still valid and not yet running) |
2059 | 2008 | for cmd in commands: |
2060 | - #if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): break | |
2009 | + #if cmd.name in ("do_exit", "do_abort", "do_flush_pending_commands"): break | |
2061 | 2010 | #if cmd.name in ("do_exit", "do_abort"): break |
2062 | 2011 | if cmd.is_agent_general_priority_cmd(): |
2063 | 2012 | if cmd.name in ("do_stop","do_restart") and self.__cmd_was_sent_before_my_start(cmd): |
... | ... | @@ -2077,7 +2026,7 @@ class Agent: |
2077 | 2026 | break |
2078 | 2027 | #return cmd |
2079 | 2028 | ''' |
2080 | - #if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): | |
2029 | + #if cmd.name in ("do_exit", "do_abort", "do_flush_pending_commands"): | |
2081 | 2030 | if cmd.name in ("do_exit", "do_abort"): |
2082 | 2031 | if cmd.is_running(): |
2083 | 2032 | return None |
... | ... | @@ -2187,7 +2136,7 @@ class Agent: |
2187 | 2136 | cmd.set_result("I am now " + state) |
2188 | 2137 | #time.sleep(1) |
2189 | 2138 | self.waitfor(1) |
2190 | - elif cmd_name in ("do_flush_commands"): | |
2139 | + elif cmd_name in ("do_flush_pending_commands"): | |
2191 | 2140 | "flush_commands received: Delete all pending commands" |
2192 | 2141 | AgentCmd.delete_pending_commands_for_agent(self.name) |
2193 | 2142 | cmd.set_result('DONE') |
... | ... | @@ -2244,7 +2193,21 @@ class Agent: |
2244 | 2193 | pass |
2245 | 2194 | |
2246 | 2195 | |
2196 | + | |
2197 | + | |
2247 | 2198 | def __process_agent_general_cmd(self, cmd:AgentCmd): |
2199 | + | |
2200 | + try: | |
2201 | + res = self.__exec_cmd_from_its_name(cmd) | |
2202 | + except (CmdExceptionUnimplemented, CmdExceptionBadArgs, CmdExceptionExecError) as e: | |
2203 | + ##cmd.set_as_pending() | |
2204 | + # These exceptions are managed at higher level : | |
2205 | + raise | |
2206 | + cmd.set_as_processed(res) | |
2207 | + log.info("...Agent GENERAL cmd has been executed") | |
2208 | + | |
2209 | + | |
2210 | + def __process_agent_general_cmd_OLD(self, cmd:AgentCmd): | |
2248 | 2211 | # GENERAL command (related to any agent) |
2249 | 2212 | |
2250 | 2213 | #self.print(f"Starting execution of an AGENT LEVEL cmd {cmd}...") |
... | ... | @@ -2282,10 +2245,10 @@ class Agent: |
2282 | 2245 | raise CmdExceptionExecError(cmd, "EXCEPTION - One specific cmd is unimplemented => "+e.cmd_name) from None |
2283 | 2246 | ''' |
2284 | 2247 | |
2285 | - #elif cmd_name in ("do_flush_commands"): | |
2286 | - elif cmd_name == "do_flush_commands": | |
2248 | + #elif cmd_name in ("do_flush_pending_commands"): | |
2249 | + elif cmd_name == "do_flush_pending_commands": | |
2287 | 2250 | "flush_commands received: Delete all pending commands" |
2288 | - self.do_flush_commands() | |
2251 | + self.do_flush_pending_commands() | |
2289 | 2252 | #cmd.set_result('DONE') |
2290 | 2253 | result = "FLUSH DONE" |
2291 | 2254 | |
... | ... | @@ -2488,26 +2451,28 @@ class Agent: |
2488 | 2451 | cmd.set_as_running() |
2489 | 2452 | self._sleep_as_soon_as_running() |
2490 | 2453 | |
2454 | + # Command EXECUTION | |
2491 | 2455 | try: |
2492 | 2456 | # equivalent to calling self.func(*cmd.args) |
2493 | 2457 | return getattr(self, func)(*args) |
2494 | - except (TypeError, AttributeError, ValueError, Exception) as e: | |
2495 | - if isinstance(e,(TypeError, AttributeError, ValueError)): | |
2496 | - # set back to PENDING because this command should never has been RUNNING | |
2497 | - cmd.set_as_pending() | |
2498 | - # Replace low level exception with high level one (CmdExceptionBadArgs) | |
2499 | - raise CmdExceptionBadArgs(cmd) from None | |
2500 | - else: | |
2501 | - # Replace any other exception raised during execution with high level one (CmdExceptionExecError) | |
2502 | - #cmd.set_as_exec_error() | |
2503 | - msg = ': '+str(e) if str(e) else '' | |
2504 | - raise CmdExceptionExecError(cmd, type(e).__name__ + msg) from None | |
2505 | - #raise e | |
2506 | - # "from None" pour ne pas afficher l'exception AttributeError (car interne) | |
2507 | - #print("I know this specific command but it is not yet implemented : ", func) | |
2508 | - ##tb = sys.exc_info()[2] | |
2509 | - ##raise AgentCmdUnimplementedException(cmd).with_traceback(tb) | |
2510 | - ##raise AgentCmdUnimplementedException(cmd).with_traceback(None) | |
2458 | + | |
2459 | + # Replace low level exception with high level one (CmdExceptionBadArgs) | |
2460 | + except (TypeError, AttributeError, ValueError, CmdExceptionBadArgs, AssertionError) as e: | |
2461 | + # set back to PENDING because this command should never has been RUNNING | |
2462 | + cmd.set_as_pending() | |
2463 | + raise CmdExceptionBadArgs(cmd) from None | |
2464 | + | |
2465 | + # Replace any other exception raised during execution with high level one (CmdExceptionExecError) | |
2466 | + except Exception as e: | |
2467 | + #cmd.set_as_exec_error() | |
2468 | + msg = ': '+str(e) if str(e) else '' | |
2469 | + raise CmdExceptionExecError(cmd, type(e).__name__ + msg) from None | |
2470 | + #raise e | |
2471 | + # "from None" pour ne pas afficher l'exception AttributeError (car interne) | |
2472 | + #print("I know this specific command but it is not yet implemented : ", func) | |
2473 | + ##tb = sys.exc_info()[2] | |
2474 | + ##raise AgentCmdUnimplementedException(cmd).with_traceback(tb) | |
2475 | + ##raise AgentCmdUnimplementedException(cmd).with_traceback(None) | |
2511 | 2476 | |
2512 | 2477 | |
2513 | 2478 | def is_agent_level_cmd(self, cmd:AgentCmd): |
... | ... | @@ -2555,17 +2520,123 @@ class Agent: |
2555 | 2520 | |
2556 | 2521 | ### |
2557 | 2522 | # ================================================================================================ |
2558 | - # AGENT GENERAL FUNCTIONS | |
2523 | + # AGENT GENERAL COMMANDS (METHODS) | |
2559 | 2524 | # ================================================================================================ |
2560 | 2525 | ### |
2561 | 2526 | |
2562 | - def do_eval(self, eval_str:str): | |
2563 | - return eval(eval_str) | |
2527 | + def get_all_cmds(self)->str: | |
2528 | + general_cmds = self.get_general_cmds() | |
2529 | + specific_cmds = self.get_specific_cmds() | |
2530 | + all_cmds = general_cmds | |
2531 | + if specific_cmds: all_cmds += ';' + specific_cmds | |
2532 | + return all_cmds | |
2564 | 2533 | |
2565 | - def do_flush_commands(self): | |
2534 | + def get_general_cmds(self)->str: | |
2535 | + return self.__get_cmds_with_args_from_names_list(AgentCmd._AGENT_GENERAL_COMMANDS) | |
2536 | + | |
2537 | + def get_specific_cmds(self)->str: | |
2538 | + return self.__get_cmds_with_args_from_names_list(self._AGENT_SPECIFIC_COMMANDS) | |
2539 | + | |
2540 | + def __get_cmds_with_args_from_names_list(self, names_list:List)->str: | |
2541 | + ''' | |
2542 | + Return the list of all specific cmds, with their arguments type (if exists) | |
2543 | + - Each cmd is separated with a ';' and presented with this format : | |
2544 | + 'cmd_name(arg1:type,arg2:type,arg3:type...)' | |
2545 | + - If cmd is (U)nimplemented, it will be returned as : | |
2546 | + 'cmd_name(U)' | |
2547 | + - If cmd is (I)nvalid (misnamed), it will be returned as : | |
2548 | + 'cmd_name(I)' | |
2549 | + - Ex: 'do_specific10(arg1:int,arg2:int,arg3:float,arg4:str,arg5:typing.Tuple[int, str, int],arg6:typing.List[int]);do_specific30();do_cmd_raising_some_exception();do_cmd_unimplemented(U)', | |
2550 | + ''' | |
2551 | + cmds = "" | |
2552 | + # For each command | |
2553 | + #for command_tuple in self._AGENT_SPECIFIC_COMMANDS: | |
2554 | + for command_tuple in names_list: | |
2555 | + | |
2556 | + cmd_name = command_tuple[0] if isinstance(command_tuple, tuple) else command_tuple | |
2557 | + #print(cmd_name) | |
2558 | + cmds += cmd_name | |
2559 | + | |
2560 | + # 1) Error case 1 - Misnamed (Invalid syntax) command (not get, set, do) (implemented or not) | |
2561 | + if not AgentCmd.is_generic(cmd_name): | |
2562 | + cmds += '(I);' | |
2563 | + continue | |
2564 | + | |
2565 | + # 2) Error case 2 - Well named command (get, set, do) but not yet implemented | |
2566 | + try: | |
2567 | + f = getattr(self, cmd_name) | |
2568 | + # Exception if exists an unimplemented command | |
2569 | + except AttributeError: | |
2570 | + # Tag this command as UNIMPLEMENTED (U) => 'cmd_name(U)' | |
2571 | + #raise CmdExceptionUnimplemented(cmd_name) from None | |
2572 | + cmds += '(U);' | |
2573 | + # next cmd | |
2574 | + continue | |
2575 | + | |
2576 | + # 3) Normal case : well named command and implemented | |
2577 | + cmds += "(" | |
2578 | + args = signature(f) | |
2579 | + #cmds += str(args) | |
2580 | + #print(cmds) | |
2581 | + #print(args.parameters) | |
2582 | + for arg in args.parameters.values(): | |
2583 | + arg_type = arg.annotation.__name__ if isinstance(arg.annotation,type) else str(arg.annotation) | |
2584 | + cmds += arg.name+":"+arg_type+"," | |
2585 | + #print("name, annot:", arg.name, arg.annotation) | |
2586 | + #print("annot.nam e:", arg.annotation.__name__) | |
2587 | + #print(type(arg.annotation)) | |
2588 | + ''' | |
2589 | + for arg in args.parameters: | |
2590 | + print(arg) | |
2591 | + arg = args.parameters[arg] | |
2592 | + #print(arg) | |
2593 | + #print("name, annot:", arg.name, arg.annotation) | |
2594 | + #print("annot.name:", arg.annotation.__name__) | |
2595 | + #print(type(arg.annotation)) | |
2596 | + arg_type = arg.annotation.__name__ if isinstance(arg.annotation,type) else str(arg.annotation) | |
2597 | + cmds += arg.name+":"+arg_type+"," | |
2598 | + ''' | |
2599 | + # cmds += str(args) | |
2600 | + if args.parameters: cmds = cmds[:-1] | |
2601 | + cmds += ");" | |
2602 | + #cmds += ";" | |
2603 | + | |
2604 | + if cmds: cmds = cmds[0:-1] | |
2605 | + #print(cmds) | |
2606 | + return cmds | |
2607 | + | |
2608 | + def do_flush_pending_commands(self): | |
2566 | 2609 | AgentCmd.delete_pending_commands_for_agent(self.name) |
2610 | + #@deprecated | |
2611 | + def do_flush_commands(self): | |
2612 | + self.do_flush_pending_commands() | |
2613 | + | |
2614 | + def get_mode(self)->str: | |
2615 | + return "MODE is " + self.__mode | |
2616 | + | |
2617 | + #def set_mode(self, mode:Season)->str: | |
2618 | + ##def set_mode(self, mode:AgentSurvey.MODE_CHOICES)->str: | |
2619 | + def set_mode(self, mode:Literal['IDLE','ROUTINE','ATTENTIVE'])->str: | |
2620 | + assert mode in AgentSurvey.MODE_CHOICES | |
2621 | + #if not cmd_args: raise ValueError() | |
2622 | + ##if not cmd_args: raise CmdExceptionBadArgs(cmd) | |
2623 | + ##mode = cmd_args[0] | |
2624 | + if mode == "IDLE": self.set_mode_idle() | |
2625 | + elif mode == "ROUTINE": self.set_mode_routine() | |
2626 | + elif mode == "ATTENTIVE": self.set_mode_attentive() | |
2627 | + else: raise CmdExceptionBadArgs(self.__CC) | |
2628 | + #cmd.set_result("I am now " + state) | |
2629 | + return "MODE is " + mode | |
2567 | 2630 | |
2568 | - def do_exec_command(self, what:str): | |
2631 | + def do_eval(self, eval_str:str): | |
2632 | + try: | |
2633 | + res = eval(eval_str) | |
2634 | + except (SyntaxError, NameError, ValueError) as e: | |
2635 | + raise CmdExceptionBadArgs(self.__CC) from None | |
2636 | + return res | |
2637 | + | |
2638 | + def do_exec_commands(self, what:Literal['stop','resume','noprio']): | |
2639 | + assert what in ['stop','resume','noprio'] | |
2569 | 2640 | # - Temporaly stop execution of new commands (let them accumulate) |
2570 | 2641 | if what == "stop": pass |
2571 | 2642 | # - Resume execution of commands (accumulated since "do_stop_exec_cmd") |
... | ... | @@ -2573,10 +2644,13 @@ class Agent: |
2573 | 2644 | # NOT PRIO |
2574 | 2645 | if what == "noprio": pass |
2575 | 2646 | # Bad arg |
2576 | - raise CmdExceptionBadArgs(self.CC) | |
2647 | + ##raise CmdExceptionBadArgs(self.CC) | |
2577 | 2648 | |
2649 | + #@deprecated | |
2650 | + def do_abort_current_command(self): self.do_stop_current("cmd") | |
2578 | 2651 | # Stop currently running cmd or routine |
2579 | - def do_stop_current(self, what:str): | |
2652 | + def do_stop_current(self, what:Literal['cmd','routine','both']): | |
2653 | + assert what in ['cmd','routine','both'] | |
2580 | 2654 | if what == "cmd": |
2581 | 2655 | self.__do_stop_current_cmd_if_exists() |
2582 | 2656 | if what == "routine": |
... | ... | @@ -2587,7 +2661,7 @@ class Agent: |
2587 | 2661 | self.__do_stop_current_routine_before_if_exists() |
2588 | 2662 | self.__do_stop_current_routine_after_if_exists() |
2589 | 2663 | # Bad arg |
2590 | - raise CmdExceptionBadArgs(self.CC) | |
2664 | + ##raise CmdExceptionBadArgs(self.CC) | |
2591 | 2665 | #FIXME: TODO |
2592 | 2666 | def __do_stop_current_cmd_if_exists(self): |
2593 | 2667 | if self.__CC_prev and self.__CC_prev.is_running(): |
... | ... | @@ -2605,15 +2679,17 @@ class Agent: |
2605 | 2679 | log.info("Aborting current routine AFTER process if exists...") |
2606 | 2680 | pass |
2607 | 2681 | |
2608 | - | |
2609 | - | |
2682 | + #@deprecated | |
2610 | 2683 | def do_exit(self): self.do_stop("asap"); |
2684 | + #@deprecated | |
2611 | 2685 | def do_abort(self): self.do_stop("now"); |
2612 | 2686 | # Stop agent asap or now |
2613 | 2687 | def do_stop(self, when:str='asap'): self.do_stop_or_restart(False, when) |
2614 | 2688 | def do_restart(self, when:str='asap'): self.do_stop_or_restart(True, when) |
2615 | - def do_stop_or_restart(self, restart:bool=False, when:str='asap'): | |
2616 | - if when not in ('asap','now','noprio'): raise CmdExceptionBadArgs(self.CC) | |
2689 | + #def do_stop_or_restart(self, restart:bool=False, when:str='asap'): | |
2690 | + def do_stop_or_restart(self, restart:bool=False, when:Literal['asap','now','noprio']='asap'): | |
2691 | + assert when in ('asap','now','noprio') | |
2692 | + ##if when not in ('asap','now','noprio'): raise CmdExceptionBadArgs(self.CC) | |
2617 | 2693 | # NOT PRIO |
2618 | 2694 | ''' |
2619 | 2695 | if when == "noprio": |
... | ... | @@ -2639,7 +2715,6 @@ class Agent: |
2639 | 2715 | |
2640 | 2716 | |
2641 | 2717 | |
2642 | - | |
2643 | 2718 | ### |
2644 | 2719 | # ================================================================================================ |
2645 | 2720 | # AGENT SPECIFIC COMMANDS (functions) |
... | ... | @@ -2743,7 +2818,7 @@ class Agent: |
2743 | 2818 | DO_IT = False |
2744 | 2819 | while not DO_IT: |
2745 | 2820 | DO_IT, cmd_full_name, validity, expected_res, expected_status = next(self.TEST_COMMANDS, (False,None,None,None,None)) |
2746 | - print(DO_IT, cmd_full_name) | |
2821 | + ##print(DO_IT, cmd_full_name) | |
2747 | 2822 | if cmd_full_name is None: return None |
2748 | 2823 | #print(expected_final_status) |
2749 | 2824 | #print(cmd_full_name, res_expected) |
... | ... | @@ -2795,7 +2870,7 @@ class Agent: |
2795 | 2870 | cmdts = self.__TEST_get_next_command_to_send() |
2796 | 2871 | # No more command to send (from simulator) => return and EXIT |
2797 | 2872 | if cmdts is None : |
2798 | - if not self.get_my_received_pending_commands().exists(): | |
2873 | + if not self.get_received_pending_commands().exists(): | |
2799 | 2874 | self.DO_MAIN_LOOP = False |
2800 | 2875 | return |
2801 | 2876 | ... | ... |
src/core/pyros_django/agent/AgentBasic.py
... | ... | @@ -86,12 +86,9 @@ class AgentBasic(Agent): |
86 | 86 | # ---------------------------------------------------- |
87 | 87 | |
88 | 88 | |
89 | - # - Error case 2 - Unimplemented command (in agent specific commands list) | |
90 | - | |
91 | - | |
92 | 89 | # - Error case 1 - CMD_INVALID |
93 | 90 | # a) Misnamed commands |
94 | - (True, "self cmd_misnamed_and_declared", 200, "Command misnamed, must start with do_, get_, or set_", Agent.CMD_STATUS.CMD_INVALID), | |
91 | + (COMMIT_ONLY, "self cmd_misnamed_and_declared", 200, "Command misnamed, must start with do_, get_, or set_", Agent.CMD_STATUS.CMD_INVALID), | |
95 | 92 | (COMMIT_ONLY, "self cmd_misnamed_and_undeclared", 200, None, Agent.CMD_STATUS.CMD_INVALID), |
96 | 93 | # b) Unknwon command |
97 | 94 | ##FIXME: ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_UNKNOWN), |
... | ... | @@ -105,9 +102,12 @@ class AgentBasic(Agent): |
105 | 102 | (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, None, Agent.CMD_STATUS.CMD_INVALID), |
106 | 103 | # - bad type |
107 | 104 | (True, "self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_INVALID), |
105 | + (True, "self set_mode unknown_mode", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
106 | + (True, "self do_eval bad_arg", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
108 | 107 | # - OK |
109 | 108 | #("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), |
110 | 109 | |
110 | + # - Error case 2 - Unimplemented command (in agent specific commands list) | |
111 | 111 | # - Error case 3 - CMD_UNIMPLEMENTED |
112 | 112 | (True, "self do_cmd_unimplemented_and_declared", 200, None, Agent.CMD_STATUS.CMD_UNIMPLEMENTED), |
113 | 113 | |
... | ... | @@ -120,19 +120,21 @@ class AgentBasic(Agent): |
120 | 120 | (COMMIT_ONLY, "self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), |
121 | 121 | (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), |
122 | 122 | # b) Back to mode ATTENTIVE, SPECIFIC commands should be executed |
123 | - (COMMIT_ONLY, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
123 | + (True, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
124 | 124 | (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), |
125 | 125 | |
126 | + | |
126 | 127 | # ---------------------------------------------------- |
127 | 128 | # ------ B - ERROR CASES - from RUNNING status ------- |
128 | 129 | # ---------------------------------------------------- |
129 | - | |
130 | 130 | |
131 | 131 | (True, "self do_cmd_raising_some_exception", 200, |
132 | 132 | #"EXCEPTION on command do_cmd_raising_some_exception: StopIteration", |
133 | 133 | "EXCEPTION on command do_cmd_raising_some_exception: StopIteration: Some exception was raised", |
134 | 134 | Agent.CMD_STATUS.CMD_EXEC_ERROR), |
135 | 135 | #(True, "self do_cmd_raising_some_exception", 200, "EXCEPTION on command do_cmd_raising_some_exception: Error during Execution", Agent.CMD_STATUS.CMD_EXEC_ERROR), |
136 | + | |
137 | + | |
136 | 138 | # ------------------------------ |
137 | 139 | # ------ C - NORMAL CASES ------- |
138 | 140 | # ------------------------------ | ... | ... |
src/core/pyros_django/common/models.py
... | ... | @@ -719,7 +719,9 @@ class AgentCmd(models.Model): |
719 | 719 | # @deprecated |
720 | 720 | "do_abort_current_command", |
721 | 721 | |
722 | - # - Remove all your pending commands | |
722 | + # - Delete all your pending commands | |
723 | + "do_flush_pending_commands", | |
724 | + #@deprecated | |
723 | 725 | "do_flush_commands", |
724 | 726 | |
725 | 727 | # - Restart your global loop (starting with init()) |
... | ... | @@ -729,6 +731,8 @@ class AgentCmd(models.Model): |
729 | 731 | # - "noprio" (not priority, priority by default) |
730 | 732 | "do_restart", # + arg "asap" (default) or "now" |
731 | 733 | |
734 | + "get_all_cmds", | |
735 | + #@deprecated | |
732 | 736 | "get_specific_cmds", |
733 | 737 | |
734 | 738 | ] |
... | ... | @@ -739,7 +743,7 @@ class AgentCmd(models.Model): |
739 | 743 | |
740 | 744 | # 1 - NO STOP commands => will not stop the Agent or any running cmd |
741 | 745 | "get_specific_cmds", |
742 | - "do_flush_commands", | |
746 | + "do_flush_pending_commands", | |
743 | 747 | "do_exec_commands" |
744 | 748 | |
745 | 749 | # 2 - PARTIAL STOP command => will just stop current running cmd (and routine) | ... | ... |