Commit ea13de961b26170acdb4b3aa789ac6ae36614817
1 parent
1c5910c6
Exists in
dev
NEW general cmd format ok : "set_radec 20 45", "set_state active", ...
Showing
9 changed files
with
207 additions
and
164 deletions
Show diff stats
src/core/pyros_django/agent/Agent.py
... | ... | @@ -232,29 +232,29 @@ class Agent: |
232 | 232 | # Default scenario to be executed |
233 | 233 | #TEST_COMMANDS = iter([ |
234 | 234 | TEST_COMMANDS_LIST = [ |
235 | - "go_active", | |
236 | - "go_idle", | |
235 | + "set_state:active", | |
236 | + "set_state:idle", | |
237 | 237 | |
238 | 238 | # specific0 not_executed_because_idle |
239 | 239 | "specific0", |
240 | 240 | |
241 | - "go_active", | |
241 | + "set_state:active", | |
242 | 242 | |
243 | 243 | # specific1 executed_because_not_idle, should complete ok |
244 | 244 | "specific1", |
245 | 245 | |
246 | 246 | # specific2 will be executed only when specific1 is finished, |
247 | 247 | # and should be aborted before end of execution, |
248 | - # because of the 1st coming "abort" command below | |
248 | + # because of the 1st coming "do_abort" command below | |
249 | 249 | "specific2", |
250 | 250 | |
251 | 251 | # specific3 should be executed only when specific2 is finished (in fact, aborted), |
252 | 252 | # and should be aborted before end of execution, |
253 | - # because of the 2nd coming "abort" command below | |
253 | + # because of the 2nd coming "do_abort" command below | |
254 | 254 | "specific3", |
255 | 255 | |
256 | 256 | # These commands should not have the time to be processed |
257 | - # because the "exit" command below should be executed before | |
257 | + # because the "do_exit" command below should be executed before | |
258 | 258 | "specific4", |
259 | 259 | "specific5", |
260 | 260 | "specific6", |
... | ... | @@ -263,22 +263,22 @@ class Agent: |
263 | 263 | |
264 | 264 | # Should abort the current running command (which should normally be specific2) |
265 | 265 | # even if commands above (specific3, ..., specific8) are already pending |
266 | - "abort", | |
266 | + "do_abort", | |
267 | 267 | |
268 | 268 | # These commands (except abort) won't be executed |
269 | 269 | # because too many commands are already pending (above) |
270 | 270 | "specific9", |
271 | - "abort", | |
272 | - "go_active", | |
273 | - "go_idle", | |
271 | + "do_abort", | |
272 | + "set_state:active", | |
273 | + "set_state:idle", | |
274 | 274 | |
275 | 275 | # Should stop the agent even before the previous pending commands are executed |
276 | - "exit", | |
276 | + "do_exit", | |
277 | 277 | |
278 | - # Because of the previous "exit" command, | |
278 | + # Because of the previous "do_exit" command, | |
279 | 279 | # these following commands should not be executed, |
280 | 280 | # and not even be added to the database command table |
281 | - "go_active", | |
281 | + "set_state:active", | |
282 | 282 | "specific10" |
283 | 283 | ] |
284 | 284 | #TEST_COMMANDS = iter(TEST_COMMANDS_LIST) |
... | ... | @@ -354,7 +354,7 @@ class Agent: |
354 | 354 | _computer_description = '' |
355 | 355 | |
356 | 356 | # Current and next command to send |
357 | - cmdts = None | |
357 | + cmdts:Command = None | |
358 | 358 | next_cmdts = None |
359 | 359 | |
360 | 360 | _agent_survey = None |
... | ... | @@ -404,13 +404,13 @@ class Agent: |
404 | 404 | raise Exception(f"Bad config file name '{config_filename}', error {str(self.config.get_last_errno())}: {str(self.config.get_last_errmsg())}") |
405 | 405 | |
406 | 406 | #TODO: : à mettre dans la config |
407 | + ''' | |
408 | + 'AgentDeviceTelescope1': 'AgentDeviceTelescopeGemini', | |
409 | + 'AgentDeviceFilterSelector1': 'AgentDeviceSBIG', | |
410 | + 'AgentDeviceShutter1': 'AgentDeviceSBIG', | |
411 | + 'AgentDeviceSensor1': 'AgentDeviceSBIG', | |
412 | + ''' | |
407 | 413 | self._my_client_agents = { |
408 | - ''' | |
409 | - 'AgentDeviceTelescope1': 'AgentDeviceTelescopeGemini', | |
410 | - 'AgentDeviceFilterSelector1': 'AgentDeviceSBIG', | |
411 | - 'AgentDeviceShutter1': 'AgentDeviceSBIG', | |
412 | - 'AgentDeviceSensor1': 'AgentDeviceSBIG', | |
413 | - ''' | |
414 | 414 | } |
415 | 415 | |
416 | 416 | ### self._agent_logs = AgentLogs.objects.create(name=self.name, message="Step __init__") |
... | ... | @@ -473,6 +473,7 @@ class Agent: |
473 | 473 | time.sleep(nbsec) |
474 | 474 | |
475 | 475 | def _get_real_agent_name_for_alias(self, agent_alias_name:str): |
476 | + #print("key is", agent_alias_name) | |
476 | 477 | if not self._my_client_agents: return agent_alias_name |
477 | 478 | return self._my_client_agents[agent_alias_name] |
478 | 479 | |
... | ... | @@ -512,7 +513,7 @@ class Agent: |
512 | 513 | # Main loop |
513 | 514 | while self.DO_MAIN_LOOP: |
514 | 515 | try: |
515 | - self.main_loop(nb_iter,FOR_REAL) | |
516 | + self._main_loop(nb_iter,FOR_REAL) | |
516 | 517 | if not self.DO_MAIN_LOOP: break |
517 | 518 | except KeyboardInterrupt: |
518 | 519 | # In case of CTRL-C, kill the current thread (process) before dying (in error) |
... | ... | @@ -522,7 +523,7 @@ class Agent: |
522 | 523 | #if self.DO_EXIT: exit(0) |
523 | 524 | |
524 | 525 | |
525 | - def main_loop(self, nb_iter:int=None, FOR_REAL:bool=True): | |
526 | + def _main_loop(self, nb_iter:int=None, FOR_REAL:bool=True): | |
526 | 527 | |
527 | 528 | # Bad number of iterations, so exit |
528 | 529 | if nb_iter is not None: |
... | ... | @@ -572,10 +573,10 @@ class Agent: |
572 | 573 | cmd = self.get_next_valid_and_not_running_command() |
573 | 574 | #if cmd: self.command_process(cmd) |
574 | 575 | if cmd: |
575 | - # GENERIC cmd : execute it always | |
576 | - if cmd.is_generic(): | |
577 | - self.exec_generic_cmd(cmd) | |
578 | - # SPECIFIC cmd : execute it only if active and no currently running specific cmd | |
576 | + # GENERAL cmd (agent level) : execute it always | |
577 | + if cmd.is_general(): | |
578 | + self.exec_general_cmd(cmd) | |
579 | + # SPECIFIC cmd (agent specific or device level) : execute it only if active and no currently running specific cmd | |
579 | 580 | else: |
580 | 581 | self.exec_specific_cmd_if_possible(cmd) |
581 | 582 | |
... | ... | @@ -878,12 +879,13 @@ class Agent: |
878 | 879 | self.print("Current pending commands are (time ordered) :") |
879 | 880 | Command.show_commands(commands) |
880 | 881 | |
881 | - # 2) If there is a "exit" or "abort" command pending (even at the end of the list), | |
882 | + # 2) If there is a "do_exit" or "do_abort" command pending (even at the end of the list), | |
882 | 883 | # which is VALID (not expired), |
883 | 884 | # then pass it straight away to general_process() for execution |
884 | 885 | for cmd in commands: |
885 | - if cmd.name in ("exit", "abort", "flush_commands"): break | |
886 | - if cmd.name in ("exit", "abort", "flush_commands"): | |
886 | + #if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): break | |
887 | + if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): break | |
888 | + if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): | |
887 | 889 | if cmd.is_running(): |
888 | 890 | return None |
889 | 891 | if cmd.is_expired(): |
... | ... | @@ -944,72 +946,7 @@ class Agent: |
944 | 946 | return cmd |
945 | 947 | |
946 | 948 | |
947 | - def AVIRER_command_process(self, cmd:Command)->Command: | |
948 | - assert cmd is not None | |
949 | - cmd = self.general_process(cmd) | |
950 | - # Sub-level loop (only if ACTIVE) | |
951 | - if cmd and self.is_active(): | |
952 | - self.specific_process(cmd) | |
953 | - | |
954 | - | |
955 | - def AVIRER_general_process(self, cmd:Command)->Command: | |
956 | - assert cmd is not None | |
957 | - | |
958 | - self.set_status(self.STATUS_GENERAL_PROCESS) | |
959 | - self.print("***") | |
960 | - self.print("*** RECEIVED", cmd) | |
961 | - self.print("***") | |
962 | - self.printd(f"Starting general processing of this command") | |
963 | - | |
964 | - # Update read time to say that the command has been READ | |
965 | - cmd.set_read_time() | |
966 | - # Precondition: command cmd is valid (not expired), has already been read, is pending | |
967 | - assert (not cmd.is_expired()) and cmd.is_pending() and cmd.is_read() | |
968 | - | |
969 | - #self.printd(f"Starting general processing of command {cmd.name} sent by agent {cmd.sender} at {cmd.sender_deposit_time}") | |
970 | - | |
971 | - """ | |
972 | - # 2) If expired command, change its status to expired and return | |
973 | - if cmd.is_expired(): | |
974 | - self.printd("This command is expired, so mark it as such, and ignore it") | |
975 | - cmd.set_as_outofdate() | |
976 | - return None | |
977 | - """ | |
978 | - | |
979 | - # If cmd is generic, execute it, change its status to executed, and return | |
980 | - if cmd.is_generic(): | |
981 | - self.print("This command is generic, execute it...") | |
982 | - self.exec_generic_cmd(cmd) | |
983 | - # If cmd is "exit", kill myself (without any question, this is an order soldier !) | |
984 | - # This "exit" should normally kill any current thread (to be checked...) | |
985 | - if cmd.name == "exit": | |
986 | - self.printd("(before exiting) Here are the current (still) pending commands (time ordered) :") | |
987 | - commands = Command.get_pending_and_running_commands_for_agent(self.name) | |
988 | - Command.show_commands(commands) | |
989 | - #if self.TEST_MODE and self.TEST_WITH_FINAL_TEST and self.TEST_COMMANDS_DEST == "myself": self.simulator_test_results() | |
990 | - if self.TEST_MODE and self.TEST_WITH_FINAL_TEST: self.simulator_test_results() | |
991 | - #self.DO_EXIT=True | |
992 | - #exit(0) | |
993 | - # Command is executed, so return None | |
994 | - return None | |
995 | - | |
996 | - # cmd is not generic | |
997 | - else: | |
998 | - # cmd is not generic but, as I am idle, change its status to SKIPPED, ignore it, and return | |
999 | - #if self.mode == self.MODE_IDLE: | |
1000 | - if self.is_idle(): | |
1001 | - self.printd("This command is not generic but, as I am IDLE, I mark it SKIPPED and ignore it") | |
1002 | - cmd.set_as_skipped() | |
1003 | - return None | |
1004 | - | |
1005 | - # Je suis pas idle et cde pas générique: je la traite pas, elle sera traitée par core_process : | |
1006 | - # attendre que cette commande soit exécutée avant de passer à la commande suivante (situation “bloquante” normale) | |
1007 | - self.printd("This command is not generic and, as I am not IDLE, I pass it to the specific processing") | |
1008 | - self.printd("(then I will not execute any other new command until this command is EXECUTED)") | |
1009 | - return cmd | |
1010 | - | |
1011 | - | |
1012 | - def exec_generic_cmd(self, cmd:Command): | |
949 | + def exec_general_cmd(self, cmd:Command): | |
1013 | 950 | |
1014 | 951 | self.printd(f"Starting execution of a GENERIC cmd {cmd}") |
1015 | 952 | |
... | ... | @@ -1018,43 +955,50 @@ class Agent: |
1018 | 955 | cmd.set_as_running() |
1019 | 956 | |
1020 | 957 | # Executing command |
1021 | - if cmd.name == "go_active": | |
1022 | - self.set_active() | |
1023 | - cmd.set_result("I am now active") | |
1024 | - time.sleep(1) | |
1025 | - elif cmd.name == "go_idle": | |
1026 | - self.set_idle() | |
1027 | - cmd.set_result("I am now idle") | |
958 | + cmd_name, cmd_args = cmd.tokenize() | |
959 | + #if cmd.name == "set_state:active": | |
960 | + #elif cmd.name == "set_state:idle": | |
961 | + if cmd_name == "set_state": | |
962 | + if not cmd_args: raise(ValueError) | |
963 | + state = cmd_args[0] | |
964 | + if state == "active": self.set_active() | |
965 | + if state == "idle": self.set_idle() | |
966 | + cmd.set_result("I am now " + state) | |
1028 | 967 | time.sleep(1) |
1029 | - elif cmd.name in ("flush_commands"): | |
968 | + elif cmd.name in ("do_flush_commands"): | |
1030 | 969 | self.print("flush_commands received: Delete all pending commands") |
1031 | 970 | Command.delete_pending_commands_for_agent(self.name) |
1032 | 971 | cmd.set_result('DONE') |
1033 | - elif cmd.name in ("abort", "exit", "restart_init"): | |
972 | + elif cmd.name in ("do_abort", "do_exit", "do_restart_init"): | |
1034 | 973 | #self.printd("Current pending commands are:") |
1035 | 974 | #Command.show_commands(self._pending_commands) |
1036 | 975 | self.print("Aborting current executing command if exists:") |
1037 | 976 | self.kill_running_specific_cmd_if_exists(cmd.sender) |
1038 | - if cmd.name == "restart_init": | |
977 | + if cmd.name == "do_restart_init": | |
1039 | 978 | self.print("restart_init received: Restarting from init()") |
1040 | 979 | self.DO_RESTART=True |
1041 | - elif cmd.name == "exit": | |
980 | + elif cmd.name == "do_exit": | |
1042 | 981 | self.DO_EXIT=True |
1043 | 982 | cmd.set_result('SHOULD BE DONE NOW') |
1044 | 983 | else: |
984 | + ''' | |
1045 | 985 | name = cmd.name |
1046 | 986 | args = None |
1047 | 987 | if " " in name: name,args = name.split() |
1048 | - if name == "eval": | |
988 | + if name == "do_eval": | |
1049 | 989 | if args==None: raise(ValueError) |
1050 | 990 | cmd.set_result(eval(args)) |
991 | + ''' | |
992 | + if cmd_name == "do_eval": | |
993 | + if not cmd_args: raise(ValueError) | |
994 | + cmd.set_result(eval(cmd_args)) | |
1051 | 995 | |
1052 | 996 | cmd.set_as_processed() |
1053 | 997 | self.printd("...Generic cmd has been executed") |
1054 | 998 | |
1055 | - # If cmd is "exit", kill myself (without any question, this is an order soldier !) | |
1056 | - # This "exit" should normally kill any current thread (to be checked...) | |
1057 | - if cmd.name == "exit": | |
999 | + # If cmd is "do_exit", kill myself (without any question, this is an order soldier !) | |
1000 | + # This "do_exit" should normally kill any current thread (to be checked...) | |
1001 | + if cmd.name == "do_exit": | |
1058 | 1002 | self.printd("(before exiting) Here are the current (still) pending commands (time ordered) :") |
1059 | 1003 | commands = Command.get_pending_and_running_commands_for_agent(self.name) |
1060 | 1004 | Command.show_commands(commands) |
... | ... | @@ -1170,15 +1114,15 @@ class Agent: |
1170 | 1114 | cmd = next(self.TEST_COMMANDS, None) |
1171 | 1115 | #return cmd_name |
1172 | 1116 | if cmd is None: return None |
1173 | - agent_recipient,cmd_name = cmd.split(':') | |
1117 | + agent_recipient,cmd_name = cmd.split(' ', 1) | |
1174 | 1118 | ##recipient_agent = self.name if self.TEST_COMMANDS_DEST=="myself" else self.TEST_COMMANDS_DEST |
1175 | 1119 | #return Command(sender=self.name, recipient=recipient_agent, name=cmd_name) |
1176 | 1120 | return self.build_cmd(agent_recipient, cmd_name) |
1177 | 1121 | |
1178 | 1122 | """ |
1179 | 1123 | def simulator_send_next_command(self): |
1180 | - #self._current_test_cmd = "go_idle" if self._current_test_cmd=="go_active" else "go_active" | |
1181 | - #if self._nb_test_cmds == 4: self._current_test_cmd = "exit" | |
1124 | + #self._current_test_cmd = "set_state:idle" if self._current_test_cmd=="set_state:active" else "set_state:active" | |
1125 | + #if self._nb_test_cmds == 4: self._current_test_cmd = "do_exit" | |
1182 | 1126 | cmd_name = next(self.TEST_COMMANDS, None) |
1183 | 1127 | #self.printd("next cmd is ", cmd_name) |
1184 | 1128 | if cmd_name is None: return |
... | ... | @@ -1196,17 +1140,17 @@ class Agent: |
1196 | 1140 | """ |
1197 | 1141 | |
1198 | 1142 | # There is a current command being processed |
1199 | - # => check if next command is "abort" | |
1200 | - # => if so, instantly send an "abort" to abort previous command | |
1143 | + # => check if next command is "do_abort" | |
1144 | + # => if so, instantly send an "do_abort" to abort previous command | |
1201 | 1145 | if self.cmdts is not None: |
1202 | - self.print(f"Waiting for end of cmd '{self.cmdts.name}' execution...") | |
1146 | + self.print(f"Waiting for end execution of cmd '{self.cmdts.name}' (sent to {self.cmdts.recipient}) ...") | |
1203 | 1147 | # Update cmdts fields from DB |
1204 | 1148 | self.cmdts.refresh_from_db() |
1205 | 1149 | if self.cmdts.is_pending() or self.cmdts.is_running(): |
1206 | 1150 | if self.next_cmdts is None: |
1207 | - # If next command is "abort" then abort becomes the new current command (to be sent) | |
1151 | + # If next command is "do_abort" then abort becomes the new current command (to be sent) | |
1208 | 1152 | self.next_cmdts = self.simulator_get_next_command_to_send() |
1209 | - if self.next_cmdts and self.next_cmdts.name == "abort": | |
1153 | + if self.next_cmdts and self.next_cmdts.name == "do_abort": | |
1210 | 1154 | # Wait a little to give a chance to agentB to start execution of current command, |
1211 | 1155 | # so that we can abort it then (otherwise it won't be aborted!!) |
1212 | 1156 | time.sleep(4) |
... | ... | @@ -1304,10 +1248,10 @@ class Agent: |
1304 | 1248 | assert cmd.is_pending() |
1305 | 1249 | nb_asserted+=1 |
1306 | 1250 | # 2 cmds abort |
1307 | - if cmd.name in ("abort"): | |
1251 | + if cmd.name in ("do_abort"): | |
1308 | 1252 | assert cmd.is_executed() |
1309 | 1253 | nb_asserted+=1 |
1310 | - if cmd.name in ("exit"): | |
1254 | + if cmd.name in ("do_exit"): | |
1311 | 1255 | assert cmd.is_executed() |
1312 | 1256 | nb_asserted+=1 |
1313 | 1257 | assert nb_asserted == 12 | ... | ... |
src/core/pyros_django/agent/AgentDevice.py
... | ... | @@ -237,6 +237,7 @@ class AgentDevice(Agent): |
237 | 237 | # Define your own command step(s) here |
238 | 238 | def cmd_step(self, step:int): |
239 | 239 | cmd = self._current_specific_cmd |
240 | + print("cmd name is", cmd.name) | |
240 | 241 | res = self._device_ctrl.execute_cmd(cmd.name) |
241 | 242 | cmd.set_result(str(res)) |
242 | 243 | print("result is", str(res)) | ... | ... |
src/core/pyros_django/agent/AgentDeviceTelescopeGemini.py
... | ... | @@ -134,21 +134,24 @@ class AgentDeviceTelescopeGemini(AgentDevice): |
134 | 134 | # @Override |
135 | 135 | def get_device_status(self): |
136 | 136 | |
137 | - cmd="get date" | |
137 | + #cmd="get date" | |
138 | + cmd="get_date" | |
138 | 139 | res = self._device_ctrl.execute_cmd(cmd) |
139 | 140 | self.printd("result is", str(res)) |
140 | 141 | if res.ok: print("OK") |
141 | 142 | dev_date = str(res) |
142 | 143 | time.sleep(1) |
143 | 144 | |
144 | - cmd="get time" | |
145 | + #cmd="get time" | |
146 | + cmd="get_time" | |
145 | 147 | res = self._device_ctrl.execute_cmd(cmd) |
146 | 148 | self.printd("result is", str(res)) |
147 | 149 | if res.ok: print("OK") |
148 | 150 | dev_time = str(res) |
149 | 151 | time.sleep(1) |
150 | 152 | |
151 | - cmd="get radec" | |
153 | + #cmd="get radec" | |
154 | + cmd="get_radec" | |
152 | 155 | res = self._device_ctrl.execute_cmd(cmd) |
153 | 156 | self.printd("result is", str(res)) |
154 | 157 | if res.ok: print("OK") | ... | ... |
src/core/pyros_django/agent/AgentMultiRequester.py
... | ... | @@ -25,9 +25,53 @@ class AgentMultiRequester(Agent): |
25 | 25 | # Who should I send commands to ? |
26 | 26 | #TEST_COMMANDS_DEST = "myself" |
27 | 27 | #TEST_COMMANDS_DEST = "AgentDeviceTelescopeGemini" |
28 | + | |
28 | 29 | # Scenario to be executed |
29 | 30 | TEST_COMMANDS_LIST = [ |
30 | 31 | # Ask receiver to delete all its previous commands |
32 | + 'ad_tele do_flush_commands', | |
33 | + ##'ad_filterselect:do_flush_commands', | |
34 | + ##'ad_shutter:do_flush_commands', | |
35 | + ##'ad_sensor:do_flush_commands', | |
36 | + | |
37 | + #'ad_tele:go_active', | |
38 | + 'ad_tele set_state active', | |
39 | + | |
40 | + # Because of this command, the receiver agent : | |
41 | + # - will no more send any new command | |
42 | + # - will only execute "generic" commands (and not the "specific" ones) | |
43 | + ##'ad_tele:set_state:idle', | |
44 | + | |
45 | + # Because of this command, the receiver agent(s) | |
46 | + # will now be able to send new commands | |
47 | + ##'ad_tele:set_state:active', | |
48 | + ##'ad_filterselect:set_state:active', | |
49 | + ##'ad_shutter:set_state:active', | |
50 | + ##'ad_sensor:set_state:active', | |
51 | + | |
52 | + 'ad_tele do_init', | |
53 | + ##'ad_filterselect:do_init', | |
54 | + ##'ad_shutter:do_init', | |
55 | + ##'ad_sensor:do_init', | |
56 | + | |
57 | + 'ad_tele do_goto_radec 15 20', | |
58 | + ##'ad_filterselect:do_goto:3', | |
59 | + | |
60 | + ##'ad_shutter:do_open', | |
61 | + ##'ad_sensor:do_acquire:7000', | |
62 | + ##'ad_shutter:do_close', | |
63 | + | |
64 | + ##'ad_sensor:do_shutdown' | |
65 | + | |
66 | + # Now stop all my device agent clients: | |
67 | + 'ad_tele do_exit', | |
68 | + ##'ad_filterselect:do_exit', | |
69 | + ##'ad_shutter:do_exit', | |
70 | + ##'ad_sensor:do_exit', | |
71 | + ] | |
72 | + | |
73 | + TEST_COMMANDS_LIST_BASIC = [ | |
74 | + # Ask receiver to delete all its previous commands | |
31 | 75 | 'AgentDeviceTelescope1:flush_commands', |
32 | 76 | 'AgentDeviceFilterSelector1:flush_commands', |
33 | 77 | 'AgentDeviceShutter1:flush_commands', |
... | ... | @@ -70,7 +114,6 @@ class AgentMultiRequester(Agent): |
70 | 114 | ] |
71 | 115 | |
72 | 116 | |
73 | - | |
74 | 117 | """ |
75 | 118 | ================================================================= |
76 | 119 | FUNCTIONS RUN INSIDE MAIN THREAD |
... | ... | @@ -85,11 +128,17 @@ class AgentMultiRequester(Agent): |
85 | 128 | super().__init__(config_filename, RUN_IN_THREAD) |
86 | 129 | |
87 | 130 | #TODO: : à mettre dans la config |
131 | + """ | |
132 | + 'AgentDeviceTelescope1': 'AgentDeviceTelescopeGemini', | |
133 | + 'AgentDeviceFilterSelector1': 'AgentDeviceSBIG', | |
134 | + 'AgentDeviceShutter1': 'AgentDeviceSBIG', | |
135 | + 'AgentDeviceSensor1': 'AgentDeviceSBIG', | |
136 | + """ | |
88 | 137 | self._my_client_agents = { |
89 | - 'AgentDeviceTelescope1': 'AgentDeviceTelescopeGemini', | |
90 | - 'AgentDeviceFilterSelector1': 'AgentDeviceSBIG', | |
91 | - 'AgentDeviceShutter1': 'AgentDeviceSBIG', | |
92 | - 'AgentDeviceSensor1': 'AgentDeviceSBIG', | |
138 | + 'ad_tele': 'AgentDeviceTelescopeGemini', | |
139 | + 'ad_filterselect': 'AgentDeviceSBIG', | |
140 | + 'ad_shutter': 'AgentDeviceSBIG', | |
141 | + 'ad_sensor': 'AgentDeviceSBIG', | |
93 | 142 | } |
94 | 143 | |
95 | 144 | #self._log.print(f"init done for {self.name}") | ... | ... |
src/core/pyros_django/agent/doc/Agent_activity_diag.pu
... | ... | @@ -53,13 +53,14 @@ while (DO_RESTART ?) is (yes) |
53 | 53 | |
54 | 54 | :routine_process(); |
55 | 55 | |
56 | + | |
56 | 57 | :cmd = get_next_valid_command(); |
57 | 58 | if (cmd ?) then |
58 | - partition command_process(cmd) { | |
59 | - :cmd = general_process(cmd); | |
60 | - if (cmd ?) then | |
61 | - :specific_process(cmd); | |
59 | + partition command_process(cmd) { | |
60 | + if (cmd.is_general ?) then | |
61 | + :exec_general_cmd(cmd); | |
62 | 62 | else (no) |
63 | + :exec_specific_cmd_if_possible(cmd); | |
63 | 64 | endif |
64 | 65 | note right |
65 | 66 | only if I am "active" |
... | ... | @@ -67,6 +68,8 @@ while (DO_RESTART ?) is (yes) |
67 | 68 | } |
68 | 69 | else (no) |
69 | 70 | endif |
71 | + | |
72 | + | |
70 | 73 | if (DO_RESTART or DO_EXIT ?) then (yes) |
71 | 74 | :DO_MAIN_LOOP = False; |
72 | 75 | endif | ... | ... |
src/core/pyros_django/common/models.py
... | ... | @@ -424,9 +424,11 @@ class Command(models.Model): |
424 | 424 | "CMD_OUTOFDATE" # cde périmée |
425 | 425 | ) |
426 | 426 | GENERIC_COMMANDS = [ |
427 | - "eval", "go_idle", "go_active", | |
428 | - # Commands executed in priority (even if other pending commands exist) | |
429 | - "flush_commands", "abort", "exit", "restart_init" | |
427 | + #"do_eval", "set_state:idle", "set_state:active", | |
428 | + "do_eval", | |
429 | + "set_state", | |
430 | + # Commands executed in priority (even if other pending commands exist) | |
431 | + "do_flush_commands", "do_abort", "do_exit", "do_restart_init" | |
430 | 432 | ] |
431 | 433 | #COMMANDS_PEREMPTION_HOURS = 48 |
432 | 434 | COMMANDS_PEREMPTION_HOURS = 60/60 |
... | ... | @@ -619,14 +621,23 @@ class Command(models.Model): |
619 | 621 | #self.save() |
620 | 622 | self.set_as_pending() |
621 | 623 | |
622 | - def is_generic(self): | |
624 | + def tokenize(self): | |
625 | + ''' | |
626 | + return: self (cmd) name and args | |
627 | + ''' | |
628 | + cmd_name, *cmd_args = self.name.split(' ') | |
629 | + return cmd_name, cmd_args | |
630 | + | |
631 | + def is_general(self): | |
623 | 632 | """ |
624 | - Is this a generic command ? | |
625 | - It is the case if command is of style "go_idle" or "go_active" or "stop"... | |
633 | + Is this a general command ? | |
634 | + It is the case if command is of style "do_set:state:idle" or "do_restart" or "do_flush"... | |
626 | 635 | """ |
627 | - name = self.name | |
628 | - if " " in name: name,args = name.split() | |
629 | - return name in self.GENERIC_COMMANDS | |
636 | + ##name = self.name | |
637 | + ##if " " in name: name,args = name.split() | |
638 | + ##name = self.name.split(' ')[0] | |
639 | + cmd_name, _ = self.tokenize() | |
640 | + return cmd_name in self.GENERIC_COMMANDS | |
630 | 641 | #"CMD_OUTOFDATE" # cde périmée |
631 | 642 | |
632 | 643 | def is_read(self): | ... | ... |
src/device_controller/abstract_component/base.py
... | ... | @@ -267,14 +267,15 @@ class DeviceControllerAbstract(): |
267 | 267 | |
268 | 268 | |
269 | 269 | def is_generic_cmd(self, raw_input_cmd:str) -> bool: |
270 | + print("raw_input_cmd is", raw_input_cmd) | |
270 | 271 | # Using Google documentation format (https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html#example-google) |
271 | 272 | """ Is this a generic command ? |
272 | 273 | |
273 | 274 | Args: |
274 | - raw_input_cmd: a command in raw string format (like 'get ra' or 'set ra 20:00:00' or 'set radec 20:00:00 90:00:00" or 'do park' or 'do_park'...) | |
275 | + raw_input_cmd: a command in string format (like 'set_state active' or 'get_ra' or 'set_ra 20:00:00' or 'set_radec 20:00:00 90:00:00" or 'do_park'...) | |
275 | 276 | |
276 | 277 | Returns: |
277 | - either False or (cmd, [values]) with cmd like "get_ra" (using underscore '_' instead of space ' '). | |
278 | + either False or (cmd, [args]) with cmd like "get_ra" and [args] like ['20:00:00', '90:00:00'] | |
278 | 279 | |
279 | 280 | """ |
280 | 281 | #return cmd.startswith('get_') or cmd.startswith('set_') or cmd.startswith('do_') |
... | ... | @@ -294,28 +295,41 @@ class DeviceControllerAbstract(): |
294 | 295 | return generic_cmd.replace(' ','_'), values |
295 | 296 | return False, False |
296 | 297 | ''' |
297 | - values_to_set = None | |
298 | - cmds = ("get","set","do") | |
298 | + ##cmds = ("get","set","do") | |
299 | + | |
300 | + ''' | |
301 | + # ex: "set radec" => "set_radec" | |
299 | 302 | raw_input_cmd = raw_input_cmd.strip() |
300 | 303 | cmd_splitted = raw_input_cmd.split(' ') |
301 | 304 | if len(cmd_splitted) == 1: return False,False |
302 | - # ex: "set_radec" | |
303 | 305 | generic_cmd = cmd_splitted[0] + '_' + cmd_splitted[1] |
306 | + ''' | |
307 | + # Ex: "set_radec 15 30", "do_init", "get_radec", "set_state active", "do_goto_radec 15 45"... | |
308 | + tokens = raw_input_cmd.split(' ') | |
309 | + generic_cmd = tokens[0] | |
310 | + | |
304 | 311 | # Check this generic command exists |
305 | 312 | #if (generic_cmd not in self._cmd.keys()): return False,False |
306 | 313 | if generic_cmd not in self._cmd: return False,False |
307 | 314 | # Is there value(s) passed ? |
308 | - if len(cmd_splitted) > 2: values_to_set = cmd_splitted[2:] | |
315 | + ###if len(cmd_splitted) > 2: values_to_set = cmd_splitted[2:] | |
316 | + args = tokens[1:] if len(tokens)>1 else None | |
309 | 317 | # ex: return "set_radec", ["20:00:00", "90:00:00"] |
310 | - return generic_cmd, values_to_set | |
318 | + return generic_cmd, args | |
311 | 319 | |
312 | 320 | |
313 | 321 | def execute_cmd(self, raw_input_cmd:str)->GenericResult: |
322 | + ''' | |
323 | + :param raw_input_cmd: | |
324 | + ''' | |
325 | + generic_cmd, args = self.is_generic_cmd(raw_input_cmd) | |
326 | + | |
314 | 327 | # GENERIC command |
315 | - generic_cmd, values = self.is_generic_cmd(raw_input_cmd) | |
316 | 328 | if generic_cmd is not False: |
317 | - #print("GENERIC COMMAND") | |
318 | - return self.execute_generic_cmd(generic_cmd, values) | |
329 | + print("GENERIC COMMAND") | |
330 | + return self.execute_generic_cmd(generic_cmd, args) | |
331 | + | |
332 | + # NATIVE command | |
319 | 333 | else: |
320 | 334 | ''' |
321 | 335 | if cmd.startswith('get_'): |
... | ... | @@ -329,7 +343,7 @@ class DeviceControllerAbstract(): |
329 | 343 | return |
330 | 344 | ''' |
331 | 345 | # NATIVE command |
332 | - #print("NATIVE COMMAND") | |
346 | + print("NATIVE COMMAND") | |
333 | 347 | res_native = self.execute_native_cmd(raw_input_cmd) |
334 | 348 | return GenericResult(res_native) |
335 | 349 | |
... | ... | @@ -427,11 +441,14 @@ class DeviceControllerAbstract(): |
427 | 441 | # Get corresponding native command: |
428 | 442 | native_cmd = native_cmd_infos[0] |
429 | 443 | if not native_cmd: raise NotImplementedError |
430 | - # ex: native_cmd == "do_init", "get_radec" | |
444 | + | |
445 | + # MACRO-COMMAND (ex: native_cmd == "do_goto", "do_init", "get_radec") | |
431 | 446 | if native_cmd == generic_cmd: |
447 | + print("MACRO-COMMAND") | |
432 | 448 | #print("cmd,val", native_cmd, values_to_set) |
433 | 449 | #res:GenericResult = self.run_func(native_cmd, *values_to_set) |
434 | - if values_to_set: | |
450 | + if values_to_set: | |
451 | + print("with args") | |
435 | 452 | res = self.run_func(native_cmd, *values_to_set) |
436 | 453 | #res = getattr(self, native_cmd)(values_to_set) |
437 | 454 | else: |
... | ... | @@ -439,12 +456,13 @@ class DeviceControllerAbstract(): |
439 | 456 | #res = getattr(self, native_cmd)() |
440 | 457 | #if res is None: res = 'ok' |
441 | 458 | # res should be a GenericResult |
442 | - if not isinstance(res,GenericResult): raise Exception("Should be a GenericResult", res) | |
459 | + if not isinstance(res, GenericResult): raise Exception("Should be a GenericResult", res) | |
443 | 460 | return res |
444 | - # ex: native_cmd == "GR" | |
461 | + | |
462 | + # NATIVE COMMAND (ex: native_cmd == "GR") | |
445 | 463 | else: |
446 | 464 | native_cmd = self.formated_cmd(native_cmd,values_to_set) |
447 | - | |
465 | + | |
448 | 466 | awaited_res_if_ok = None |
449 | 467 | if len(native_cmd_infos) > 1: awaited_res_if_ok = native_cmd_infos[1] |
450 | 468 | #native_res = self.execute_native_cmd(self.formated_cmd(native_cmd,value), awaited_res_ok) | ... | ... |
src/device_controller/abstract_component/telescope.py
... | ... | @@ -109,7 +109,8 @@ class DeviceControllerTelescope(DeviceControllerAbstract): |
109 | 109 | # DO commands: |
110 | 110 | ##'do_init': ['do_init'], |
111 | 111 | ##'do_park': [], |
112 | - 'do_goto': [], | |
112 | + 'do_goto': ['do_goto'], | |
113 | + 'do_goto_radec': ['do_goto_radec'], | |
113 | 114 | 'do_move': [], |
114 | 115 | 'do_movenorth': [], |
115 | 116 | 'do_movesouth': [], |
... | ... | @@ -273,11 +274,15 @@ class DeviceControllerTelescope(DeviceControllerAbstract): |
273 | 274 | @generic_cmd |
274 | 275 | def do_prec_refr(self): pass |
275 | 276 | |
276 | - | |
277 | - | |
277 | + | |
278 | 278 | # MACRO generic command |
279 | 279 | def do_init(self): |
280 | - | |
280 | + | |
281 | + print("...STARTING TELESCOPE INITIALIZATION...") | |
282 | + time.sleep(1) | |
283 | + print("...TELESCOPE INITIALIZATION ENDED") | |
284 | + return GenericResult("OK") | |
285 | + | |
281 | 286 | ''' |
282 | 287 | 1) Send cde ACK ('06') and check answer to see if telescope is ready (see doc page 100) |
283 | 288 | (utile pour savoir si tout est ok ; par ex, si une raquette est branchée sur le tele, ça peut bloquer le protocole) |
... | ... | @@ -465,10 +470,18 @@ class DeviceControllerTelescope(DeviceControllerAbstract): |
465 | 470 | - radec.goto() |
466 | 471 | ''' |
467 | 472 | # MACRO generic command |
473 | + def do_goto_radec(self, ra, dec, speed_rate=None): return self.do_goto(ra, dec, speed_rate) | |
468 | 474 | def do_goto(self, ra, dec, speed_rate=None): |
469 | 475 | |
476 | + # TODO: remove | |
477 | + print("...Starting GOTO...") | |
478 | + time.sleep(3) | |
479 | + radec = self.get_radec() | |
480 | + print("...GOTO ended OK") | |
481 | + return GenericResult("OK") | |
482 | + | |
470 | 483 | # 1) set speed |
471 | - if speed_rate: self.set_speed(speed_rate) | |
484 | + if speed_rate : self.set_speed(speed_rate) | |
472 | 485 | |
473 | 486 | radec = self.get_radec() |
474 | 487 | print("Current position is", radec) | ... | ... |
src/device_controller/concrete_component/gemini/client_telescope_gemini_controller_run.py
... | ... | @@ -101,12 +101,13 @@ def main(): |
101 | 101 | #req = input("\n(EXPERT MODE) REQUEST TO SERVER [ex: '6' (ACK), ':GD#' (Get Dec), ':GR#' (Get RA)'], (ENTER to quit): ").strip() |
102 | 102 | cmd = input("REQUEST TO SERVER (ENTER to quit): >>> ").strip() |
103 | 103 | if not cmd: break |
104 | - | |
104 | + | |
105 | + #res = tele_ctrl.execute_cmd(cmd.replace(' ', '_')) | |
105 | 106 | res = tele_ctrl.execute_cmd(cmd) |
106 | 107 | print("result is", str(res)) |
107 | 108 | if res.ok: print("OK") |
108 | 109 | #print("result.txt is", res.txt) |
109 | - | |
110 | + | |
110 | 111 | # END: park telescope |
111 | 112 | ###tele_ctrl.do_PARK() |
112 | 113 | ... | ... |