Commit 1cf4a67f292945bd0d77cba80019fe7f53eda75c

Authored by Etienne Pallier
1 parent 51c0662b
Exists in dev

Affichage console CLEAN en mode normal (NO DEBUG) !

pyros.py
... ... @@ -19,7 +19,7 @@ import time
19 19 *****************************************************************
20 20 """
21 21  
22   -DEBUG = False
  22 +#DEBUG = False
23 23  
24 24 PYROS_DJANGO_BASE_DIR = "src/core/pyros_django"
25 25  
... ... @@ -134,7 +134,7 @@ def die(msg: str = ""):
134 134 def execProcess(command, from_venv=False, is_async=False):
135 135 from_venv_str = " from venv ("+VENV_BIN+")" if from_venv else ""
136 136 #printFullTerm(Colors.BLUE, "Executing command" + " [" + command + "]" + from_venv_str)
137   - print("Executing command" + " [" + command + "]" + from_venv_str)
  137 + printd("Executing command" + " [" + command + "]" + from_venv_str)
138 138 if from_venv: command = VENV_BIN+' ' + command
139 139 process = subprocess.Popen(command, shell=True)
140 140 if is_async:
... ... @@ -220,6 +220,9 @@ def global_test_options(func):
220 220 return func
221 221 '''
222 222  
  223 +def printd(*args, **kwargs):
  224 + if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
  225 +
223 226 GLOBAL_OPTIONS = {}
224 227 def verbose_mode(): return GLOBAL_OPTIONS["verbose"]
225 228 def test_mode(): return GLOBAL_OPTIONS["test"]
... ... @@ -237,8 +240,7 @@ def debug_mode(): return GLOBAL_OPTIONS["debug"]
237 240 def pyros_launcher(debug, sim, test, verbose):
238 241 #pass
239 242 os.environ['PYROS_DEBUG'] = '1' if debug else '0'
240   - if debug:
241   - click.echo('DEBUG mode')
  243 + if debug: click.echo('DEBUG mode')
242 244 if sim: click.echo('Starting and connecting to simulator instead of real device')
243 245 if test: click.echo('Test mode')
244 246 if verbose: click.echo('Verbose mode')
... ... @@ -308,8 +310,8 @@ def dbshell():
308 310 #@global_test_options
309 311 def install(packages_only, database_only):
310 312 print("Running install command")
311   - print("packages_only", packages_only)
312   - print("database_only", database_only)
  313 + print("- packages_only:", packages_only)
  314 + print("- database_only:", database_only)
313 315 #if test_mode(): print("in test mode")
314 316 # self.execProcess("python3 install/install.py install")
315 317 # if (os.path.basename(os.getcwd()) != "private"):
... ... @@ -416,9 +418,9 @@ def initdb():
416 418 #@click.option('--port', default=8000)
417 419 #def start(agent:str, configfile:str, test, verbosity):
418 420 def start(agent:str, configfile:str):
419   - print("Running start command")
  421 + printd("Running start command")
420 422 if configfile:
421   - print("With config file", configfile)
  423 + printd("With config file", configfile)
422 424 else:
423 425 configfile = ''
424 426 #if test_mode(): print("in test mode")
... ... @@ -453,8 +455,8 @@ def start(agent:str, configfile:str):
453 455 #if agent_name == "agentX":
454 456  
455 457 # execProcessFromVenvAsync(VENV_BIN + " manage.py runserver")
456   - print(VENV_BIN)
457   - print("Launching agent", agent_name, "...")
  458 + printd(VENV_BIN)
  459 + printd("Launching agent", agent_name, "...")
458 460 #if not test_mode(): execProcess(VENV_BIN + " manage.py runserver")
459 461 #if not test_mode(): execProcessFromVenv("start_agent_" + agent_name + ".py " + configfile)
460 462  
... ... @@ -500,7 +502,7 @@ def start(agent:str, configfile:str):
500 502 #for (p,agent) in current_processes:
501 503 for process in current_processes:
502 504 p,agent,_ = process
503   - print(f"************ Waiting for end of execution of agent {agent} ************")
  505 + printd(f"************ Waiting for end of execution of agent {agent} ************")
504 506 p.wait()
505 507 process[2] = p.returncode
506 508 print(f"************ END of execution of agent {agent} ************")
... ... @@ -529,6 +531,7 @@ def start(agent:str, configfile:str):
529 531 return True if p.returncode==0 else False
530 532  
531 533  
  534 +# TODO: implรฉmenter le STOP !!!
532 535 @pyros_launcher.command(help="Kill an agent")
533 536 @click.argument('agent')
534 537 def stop(agent):
... ... @@ -594,9 +597,9 @@ def change_dir(path):
594 597 global _previous_dir
595 598 if path == "PREVIOUS": path=_previous_dir
596 599 _previous_dir = os.getcwd()
597   - if DEBUG: print("Moving to : " + path)
  600 + printd("Moving to : " + path)
598 601 os.chdir(path)
599   - if DEBUG: print("Current directory : " + str(os.getcwd()))
  602 + printd("Current directory : " + str(os.getcwd()))
600 603  
601 604  
602 605  
... ...
src/core/pyros_django/agent/Agent.py
... ... @@ -54,7 +54,13 @@ py_pwd = os.path.normpath(os.getcwd() + "/../../../..")
54 54 if (py_pwd not in os.sys.path):
55 55 (os.sys.path).append(py_pwd)
56 56 ##sys.path.append("src")
57   -print("Starting with this sys.path", sys.path)
  57 +
  58 +
  59 +def printd(*args, **kwargs):
  60 + if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
  61 +
  62 +
  63 +printd("Starting with this sys.path", sys.path)
58 64  
59 65 # DJANGO setup
60 66 # self.printd("file is", __file__)
... ... @@ -62,7 +68,7 @@ print("Starting with this sys.path", sys.path)
62 68 # Go into src/
63 69 ##os.chdir("..")
64 70 ##os.chdir("src")
65   -print("Current directory : " + str(os.getcwd()))
  71 +printd("Current directory : " + str(os.getcwd()))
66 72  
67 73 #os.environ.setdefault("DJANGO_SETTINGS_MODULE", "src.core.pyros_django.pyros.settings")
68 74 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "src.core.pyros_django.pyros.settings")
... ... @@ -72,8 +78,8 @@ import django
72 78  
73 79 django.setup()
74 80  
75   -print("DB2 used is:", djangosettings.DATABASES["default"]["NAME"])
76   -print()
  81 +printd("DB2 used is:", djangosettings.DATABASES["default"]["NAME"])
  82 +printd()
77 83  
78 84  
79 85 """
... ... @@ -128,11 +134,6 @@ log = L.setupLogger("AgentLogger", "Agent")
128 134 IS_WINDOWS = platform.system() == "Windows"
129 135  
130 136  
131   -def printd(*args, **kwargs):
132   - if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
133   -
134   -
135   -
136 137 class Colors:
137 138 HEADER = "\033[95m"
138 139 BLUE = "\033[94m"
... ... @@ -397,7 +398,7 @@ class Agent:
397 398 #def __init__(self, name:str="Agent", config_filename:str=None, RUN_IN_THREAD=True):
398 399 def __init__(self, config_filename:str=None, RUN_IN_THREAD=True, DEBUG_MODE=False):
399 400 #self.name = name
400   - print("*** ENVIRONMENT VARIABLE PYROS_DEBUG is:", os.environ.get('PYROS_DEBUG'), '***')
  401 + printd("*** ENVIRONMENT VARIABLE PYROS_DEBUG is:", os.environ.get('PYROS_DEBUG'), '***')
401 402 self.name = self.__class__.__name__
402 403 self.DEBUG_MODE = DEBUG_MODE
403 404 self._log = LogPyros(self.name, AgentLogs)
... ... @@ -619,7 +620,7 @@ class Agent:
619 620  
620 621 #self.waitfor(self.mainloop_waittime)
621 622  
622   - self.print("-"*20, "MAIN LOOP ITERATION (END)", "-"*20)
  623 + self.print("*"*20, "MAIN LOOP ITERATION (END)", "*"*20)
623 624 #self.do_log(LOG_DEBUG, "Ending main loop iteration")
624 625  
625 626 self._iter_num += 1
... ... @@ -629,8 +630,10 @@ class Agent:
629 630  
630 631 for i in range(3): self.print()
631 632 #self.printd("-"*80)
632   - self.print("-"*20, f"MAIN LOOP ITERATION {self._iter_num} (START)", "-"*20)
633   - self.print(f"Iteration {self._iter_num}")
  633 + self.print("*"*73)
  634 + self.print("*"*20, f"MAIN LOOP ITERATION {self._iter_num} (START)", "*"*20)
  635 + self.print("*"*73, '\n')
  636 + #self.print(f"Iteration {self._iter_num}")
634 637  
635 638 # EXIT because of nb of iterations ?
636 639 if nb_iter is not None:
... ... @@ -663,25 +666,33 @@ class Agent:
663 666 def _command_process_if_exists(self):
664 667 ''' Processing the next pending command if exists '''
665 668  
666   - self.print("\n\n--------- START NEXT COMMAND PROCESSING ---------")
  669 + self.print()
  670 + self.print()
  671 + self.print("*"*10, "NEXT COMMAND PROCESSING (START)", "*"*10, '\n')
  672 +
667 673  
668 674 # Purge commands (every N iterations, delete old commands)
669 675 N=5
670 676 if ((self._iter_num-1) % N) == 0:
671   - self.print("Looking for old commands to purge...")
  677 + self.print("Purging old commands if exists")
672 678 #Command.purge_old_commands_for_agent(self.name)
673 679 self._purge_old_commands_sent_to_me()
674 680  
675 681 # Get next command and process it (if exists)
676 682 cmd = self._get_next_valid_and_not_running_command()
  683 + #self._set_status(self.STATUS_GENERAL_PROCESS)
677 684 #if cmd: self.command_process(cmd)
678 685 if cmd:
  686 + self.print('-'*6)
  687 + self.print('-'*6, "RECEIVED NEW COMMAND TO PROCESS:")
  688 + self.print('-'*6, cmd)
  689 + self.print('-'*6)
679 690  
680 691 # CASE 1 - AGENT LEVEL command
681 692 # => I process it directly without asking my DC
682 693 # => Simple action, short execution time, so I execute it directly (in current main thread, not in parallel)
683 694 if self.is_agent_level_cmd(cmd):
684   - self.print("********** AGENT LEVEL CMD *********")
  695 + self.print("(AGENT LEVEL CMD)")
685 696 try:
686 697 self._exec_agent_cmd(cmd)
687 698 except AttributeError as e:
... ... @@ -718,7 +729,7 @@ class Agent:
718 729 # => Execute it only if I am active and no currently running another device level cmd
719 730 # => Long execution time, so I will execute it in parallel (in a new thread or process)
720 731 elif self.is_device_level_cmd(cmd):
721   - self.print("********** DEVICE LEVEL CMD *********")
  732 + self.print("(DEVICE LEVEL CMD)")
722 733 try:
723 734 self.exec_device_cmd_if_possible(cmd)
724 735 except (UnimplementedGenericCmdException, UnknownNativeCmdException) as e:
... ... @@ -739,14 +750,15 @@ class Agent:
739 750 cmd.set_result("ERROR: INVALID COMMAND")
740 751 cmd.set_as_skipped()
741 752  
  753 + self.print()
  754 + self.print("*"*10, "NEXT COMMAND PROCESSING (END)", "*"*10, "\n")
742 755  
743   - self.print("\n--------- END NEXT COMMAND PROCESSING ---------\n")
744 756  
745 757  
746 758 def print_TEST_MODE(self):
747 759 if self.TEST_MODE:
748   - self.print("[IN TEST MODE]")
749   - self.print("flush previous commands to be sure to start in clean state")
  760 + self.printd("[IN TEST MODE]")
  761 + self.print("Flush previous commands to be sure to start in clean state")
750 762 Command.delete_pending_commands_for_agent(self.name)
751 763 else:
752 764 self.printd("[IN NORMAL MODE]")
... ... @@ -764,10 +776,14 @@ class Agent:
764 776 (or just a regular processing)
765 777 at each iteration
766 778 """
767   - self.print("\n\n--------- START ROUTINE PROCESSING ---------")
  779 + self.print()
  780 + self.print()
  781 + self.print("*"*10, "ROUTINE PROCESSING (START)", "*"*10, '\n')
  782 +
768 783 self._set_status(self.STATUS_ROUTINE_PROCESS)
769 784 self.routine_process_body()
770   - self.print("\n--------- END ROUTINE PROCESSING ---------\n")
  785 + self.print()
  786 + self.print("*"*10, "ROUTINE PROCESSING (END)", "*"*10)
771 787  
772 788 # To be overridden by subclasses
773 789 def routine_process_body(self):
... ... @@ -1036,7 +1052,7 @@ class Agent:
1036 1052 Commands are read in chronological order
1037 1053 """
1038 1054 self._set_status(self.STATUS_GET_NEXT_COMMAND)
1039   - #self.print("Looking for new commands from the database ...")
  1055 + self.print("Looking for a new command to process (sent by another agent):")
1040 1056  
1041 1057 # 1) Get all pending commands for me (return if None)
1042 1058 # Not sure this is necessary to do it in a transaction,
... ... @@ -1046,9 +1062,9 @@ class Agent:
1046 1062 self._pending_commands = Command.get_pending_and_running_commands_for_agent(self.name)
1047 1063 commands = self._pending_commands
1048 1064 if not commands.exists():
1049   - self.print("No new command to process")
  1065 + self.print("<None>")
1050 1066 return None
1051   - self.printd("Current pending (or running) commands are (time ordered) :")
  1067 + self.printd("Current pending (or running) commands are (time ordered):")
1052 1068 Command.show_commands(commands)
1053 1069  
1054 1070 # 2) If there is a "do_exit" or "do_abort" command pending (even at the end of the list),
... ... @@ -1056,8 +1072,9 @@ class Agent:
1056 1072 # then pass it straight away to general_process() for execution
1057 1073 for cmd in commands:
1058 1074 #if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): break
1059   - if cmd.name in ("do_exit", "do_abort", "do_flush_commands"): break
1060   - if cmd.name in ("do_exit", "do_abort", "do_flush_commands"):
  1075 + if cmd.name in ("do_exit", "do_abort"): break
  1076 + #if cmd.name in ("do_exit", "do_abort", "do_flush_commands"):
  1077 + if cmd.name in ("do_exit", "do_abort"):
1061 1078 if cmd.is_running():
1062 1079 return None
1063 1080 if cmd.is_expired():
... ... @@ -1110,11 +1127,7 @@ class Agent:
1110 1127 # 6) Current cmd must now be a valid (not expired) and PENDING one,
1111 1128 # so return it for execution
1112 1129 #self.printd(f"Got command {cmd.name} sent by agent {cmd.sender} at {cmd.sender_deposit_time}")
1113   - self._set_status(self.STATUS_GENERAL_PROCESS)
1114   - self.print("***")
1115   - self.print("*** RECEIVED", cmd)
1116   - self.print("***")
1117   - self.print(f"Starting processing of this command")
  1130 + #self.printd(f"Starting processing of this command")
1118 1131 return cmd
1119 1132  
1120 1133  
... ... @@ -1122,7 +1135,8 @@ class Agent:
1122 1135 #def _exec_agent_general_cmd(self, cmd:Command):
1123 1136 def _exec_agent_cmd(self, cmd:Command):
1124 1137  
1125   - self.print(f"Starting execution of an AGENT LEVEL cmd {cmd}")
  1138 + #self.print(f"Starting execution of an AGENT LEVEL cmd {cmd}...")
  1139 + self.print(f"Starting execution of an AGENT LEVEL cmd...")
1126 1140  
1127 1141 # Update read time to say that the command has been READ
1128 1142 cmd.set_read_time()
... ... @@ -1130,7 +1144,7 @@ class Agent:
1130 1144  
1131 1145 # SPECIFIC command (only related to me, not to any agent)
1132 1146 if self._is_agent_specific_cmd(cmd):
1133   - self.print("********** -- Agent Level SPECIFIC CMD")
  1147 + self.print("(Agent level SPECIFIC cmd)")
1134 1148 # Execute method self."cmd.name"()
1135 1149 # This can raise an exception (caught by this method caller)
1136 1150 self.exec_cmd_from_its_name(cmd)
... ... @@ -1146,11 +1160,11 @@ class Agent:
1146 1160 '''
1147 1161 cmd.set_result("Agent level SPECIFIC cmd done")
1148 1162 cmd.set_as_processed()
1149   - self.print("********** -- Agent Level SPECIFIC cmd has been executed")
  1163 + self.print("...Agent level SPECIFIC cmd has been executed")
1150 1164 return
1151 1165  
1152 1166 # GENERAL command (related to any agent)
1153   - self.print("********** -- Agent Level GENERAL CMD")
  1167 + self.print("(Agent level GENERAL CMD)")
1154 1168 _,cmd_name,cmd_args = cmd.get_full_name_parts()
1155 1169 #cmd_name, cmd_args = cmd.tokenize()
1156 1170 #if cmd.name == "set_state:active":
... ... @@ -1191,16 +1205,17 @@ class Agent:
1191 1205 cmd.set_result(eval(cmd_args))
1192 1206  
1193 1207 cmd.set_as_processed()
1194   - self.print("********** -- Agent Level GENERAL cmd has been executed")
  1208 + self.print("...Agent level GENERAL cmd has been executed")
1195 1209  
1196 1210 # If cmd is "do_exit", kill myself (without any question, this is an order soldier !)
1197 1211 # This "do_exit" should normally kill any current thread (to be checked...)
1198 1212 if cmd.name == "do_exit":
1199   - self.print("(before exiting) Here are the current (still) pending commands (time ordered) :")
  1213 + self.print("Before exiting, Here are (if exists) the current (still) pending commands (time ordered) :")
1200 1214 commands = Command.get_pending_and_running_commands_for_agent(self.name)
1201   - Command.show_commands(commands)
  1215 + Command.show_commands(commands, True)
1202 1216 #if self.TEST_MODE and self.TEST_WITH_FINAL_TEST and self.TEST_COMMANDS_DEST == "myself": self.simulator_test_results()
1203   - if self.TEST_MODE and self.TEST_WITH_FINAL_TEST: self._TEST_test_results()
  1217 + if self.TEST_MODE and self.TEST_WITH_FINAL_TEST:
  1218 + self._TEST_test_results()
1204 1219 #self._DO_EXIT=True
1205 1220 #exit(0)
1206 1221  
... ... @@ -1330,6 +1345,7 @@ class Agent:
1330 1345 TEST MODE ONLY
1331 1346 """
1332 1347  
  1348 + self.print("(TEST mode) Trying to send a new command if possible...")
1333 1349 # There is a current command being processed
1334 1350 # => check if next command is "do_abort"
1335 1351 # => if so, instantly send a "do_abort" to abort previous command
... ... @@ -1398,10 +1414,10 @@ class Agent:
1398 1414 self._DO_MAIN_LOOP = False
1399 1415 return
1400 1416 # Send cmd (= set as pending and save)
1401   - self.printd("***")
  1417 + self.print("***")
1402 1418 #self.printd(f"*** SEND ", self._cmdts)
1403   - self.printd(f"***", self._cmdts)
1404   - self.printd("***")
  1419 + self.print(f"*** NEW COMMAND TO SEND is:", self._cmdts)
  1420 + self.print("***")
1405 1421 #self._cmdts.set_as_pending()
1406 1422 # SEND
1407 1423 self._cmdts.send()
... ... @@ -1464,7 +1480,8 @@ class Agent:
1464 1480 self._TEST_test_results_end(nb_asserted)
1465 1481  
1466 1482 def _TEST_test_results_start(self):
1467   - self.print("\n--- Testing if the commands I SENT had the awaited result")
  1483 + self.print()
  1484 + self.print("--- Testing if the commands I SENT had the awaited result")
1468 1485 self.print("Here are the last commands I sent:")
1469 1486 #commands = list(Command.get_last_N_commands_for_agent(self.name, 16))
1470 1487 #commands = Command.get_last_N_commands_sent_to_agent(self.name, 16)
... ... @@ -1539,7 +1556,7 @@ def extract_parameters():
1539 1556 WITH_SIM = False
1540 1557 VERBOSE_MODE = False
1541 1558 configfile = None
1542   - print("args:", sys.argv)
  1559 + printd("args:", sys.argv)
1543 1560 for arg in sys.argv[1:] :
1544 1561 if arg == "-t": TEST_MODE = True
1545 1562 elif arg == "-s": WITH_SIM = True
... ...
src/core/pyros_django/agent/AgentDevice.py
... ... @@ -192,7 +192,7 @@ class AgentDevice(Agent):
192 192  
193 193 # @override parent class (Agent)
194 194 def routine_process_body(self):
195   - self.printd("Reading my dedicated device status information and storing it in DB)...")
  195 + self.print("Getting my device status information and storing it in DB)")
196 196  
197 197 # Save current device status to DB
198 198 #AgentDeviceTelescopeStatus.objects.create(radec=myradec)
... ... @@ -227,7 +227,9 @@ class AgentDevice(Agent):
227 227 def exec_device_cmd_if_possible(self, cmd:Command):
228 228  
229 229 self._set_status(self.STATUS_SPECIFIC_PROCESS)
230   - self.print(f"Starting execution of a DEVICE cmd {cmd}")
  230 + #self.print(f"Starting execution of a DEVICE cmd {cmd}")
  231 + self.print("Starting execution of a DEVICE cmd...")
  232 + self.printd(cmd)
231 233  
232 234 if self._is_idle():
233 235 self.print("I am IDLE ==> I mark the cmd SKIPPED and ignore it")
... ... @@ -256,9 +258,10 @@ class AgentDevice(Agent):
256 258 cmd.set_read_time()
257 259 #self._current_thread = threading.Thread(target=self.exec_command)
258 260  
  261 + self.print("Launching device cmd in a thread (or process)...")
259 262 # Run in a thread
260 263 if self.RUN_IN_THREAD:
261   - self.print("(run device cmd in a thread)")
  264 + self.printd("(run device cmd in a thread)")
262 265 self._current_device_cmd_thread = StoppableThreadEvenWhenSleeping(target=self._thread_exec_device_cmd)
263 266 #self._current_device_cmd_thread = StoppableThreadEvenWhenSleeping(target=self.exec_specific_cmd, args=(cmd,))
264 267 #self._current_thread = threading.Thread(target=self.exec_command)
... ... @@ -268,7 +271,7 @@ class AgentDevice(Agent):
268 271  
269 272 # Run in a process
270 273 else:
271   - self.print("(run cmd in a process)")
  274 + self.printd("(run cmd in a process)")
272 275 # close the database connection first, it will be re-opened in each process
273 276 db.connections.close_all()
274 277 self._current_device_cmd_thread = multiprocessing.Process(target=self._thread_exec_device_cmd)
... ... @@ -497,7 +500,7 @@ class AgentDevice(Agent):
497 500 with transaction.atomic():
498 501 cmd.set_as_processed()
499 502 """
500   - self.tprintd(">>>>> Thread: ended execution of command", cmd.name)
  503 + self.print(f">>>>> Thread: ended execution of command '{cmd.name}'")
501 504 cmd = None
502 505 # No more current thread
503 506 #self._current_device_cmd_thread = None
... ... @@ -543,6 +546,7 @@ class AgentDevice(Agent):
543 546 #cmd = self._current_device_cmd
544 547 self.tprintd("*** DEVICE cmd name is", cmd.name)
545 548 self.tprintd("*** PASS IT TO DEVICE TYPE", cmd.device_type)
  549 + time.sleep(2)
546 550 try:
547 551 res = self._device_ctrl.exec_cmd(cmd.full_name)
548 552 except (DCCNotFoundException, UnimplementedGenericCmdException) as e:
... ...
src/core/pyros_django/agent/AgentDeviceGemini.py
... ... @@ -76,8 +76,7 @@ class AgentDeviceGemini(AgentDevice):
76 76 super().__init__(
77 77 config_filename,
78 78 RUN_IN_THREAD,
79   - device_controller=DC_Gemini,
80   - host=self.HOST, port=self.PORT,
  79 + device_controller=DC_Gemini, host=self.HOST, port=self.PORT,
81 80 DEBUG_MODE=DEBUG_MODE)
82 81 ###device_simulator=DeviceSimulatorTelescopeGemini)
83 82  
... ...
src/core/pyros_django/agent/AgentDeviceSBIG.py
... ... @@ -64,7 +64,7 @@ class AgentDeviceSBIG(AgentDevice):
64 64 """
65 65  
66 66 # @override
67   - def __init__(self, config_filename=None, RUN_IN_THREAD=True):
  67 + def __init__(self, config_filename=None, RUN_IN_THREAD=True, DEBUG_MODE=False):
68 68 '''
69 69 if self.is_in_simulator_mode() and not self.WITH_SIMULATOR:
70 70 # START device SIMULATOR (in a thread) so that we can connect to it in place of the real device
... ... @@ -76,7 +76,8 @@ class AgentDeviceSBIG(AgentDevice):
76 76 super().__init__(
77 77 config_filename,
78 78 RUN_IN_THREAD,
79   - device_controller=DC_SBIG, host=self.HOST, port=self.PORT)
  79 + device_controller=DC_SBIG, host=self.HOST, port=self.PORT,
  80 + DEBUG_MODE=DEBUG_MODE)
80 81 #device_simulator=DeviceSimulatorSBIG)
81 82  
82 83 # Initialize the device table status
... ...
src/core/pyros_django/agent/AgentMultiRequester.py
... ... @@ -21,7 +21,7 @@ class AgentMultiRequester(Agent):
21 21 # Run the assertion tests at the end
22 22 TEST_WITH_FINAL_TEST = True
23 23 #TEST_MAX_DURATION_SEC = None
24   - TEST_MAX_DURATION_SEC = 150
  24 + TEST_MAX_DURATION_SEC = 200
25 25 # Who should I send commands to ?
26 26 #TEST_COMMANDS_DEST = "myself"
27 27 #TEST_COMMANDS_DEST = "AgentDeviceTelescopeGemini"
... ... @@ -30,15 +30,15 @@ class AgentMultiRequester(Agent):
30 30  
31 31 TEST_COMMANDS_LIST_GEMINI_AND_SBIG_SIMPLE = [
32 32 'ad_mount do_flush_commands',
33   - 'ad_filtersel do_flush_commands',
  33 + ##'ad_filtersel do_flush_commands',
34 34  
35 35 # Not executed because not known by Mount (but by the general DC Gemini only)
36 36 'ad_mount get_date',
37 37  
38 38 # for test purpose only
39   - 'ad_sensor get_date',
40   - 'ad_sensor set_date 21/10/19',
41   - 'ad_sensor get_date',
  39 + ##'ad_sensor get_date',
  40 + ##'ad_sensor set_date 21/10/19',
  41 + ##'ad_sensor get_date',
42 42  
43 43 'ad_mount get_ra',
44 44 #'ad_mount get_dec',
... ... @@ -55,7 +55,7 @@ class AgentMultiRequester(Agent):
55 55  
56 56 # Optional
57 57 'ad_mount do_exit',
58   - 'ad_filtersel do_exit',
  58 + ##'ad_filtersel do_exit',
59 59 ]
60 60 TEST_COMMANDS_LIST_GEMINI_AND_SBIG = [
61 61 # Ask receiver to delete all its previous commands
... ... @@ -223,9 +223,9 @@ class AgentMultiRequester(Agent):
223 223  
224 224 ]
225 225  
226   - TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_GEMINI_AND_SBIG
227 226 TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_SBIG_ONLY
228 227 TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_GEMINI_AND_SBIG_SIMPLE
  228 + TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_GEMINI_AND_SBIG
229 229  
230 230  
231 231 """
... ... @@ -236,10 +236,10 @@ class AgentMultiRequester(Agent):
236 236  
237 237 # @override
238 238 #def __init__(self, name:str=None, config_filename=None, RUN_IN_THREAD=True):
239   - def __init__(self, config_filename=None, RUN_IN_THREAD=True):
  239 + def __init__(self, config_filename=None, RUN_IN_THREAD=True, DEBUG_MODE=False):
240 240 ##if name is None: name = self.__class__.__name__
241 241 #super().__init__(name, config_filename, RUN_IN_THREAD)
242   - super().__init__(config_filename, RUN_IN_THREAD)
  242 + super().__init__(config_filename, RUN_IN_THREAD, DEBUG_MODE=DEBUG_MODE)
243 243  
244 244 #TODO: : ร  mettre dans la config
245 245 """
... ...
src/core/pyros_django/common/models.py
1 1 ##from __future__ import unicode_literals
2 2  
  3 +# Stdlib imports
3 4 from enum import Enum
4 5 from datetime import datetime, timedelta
  6 +import os
  7 +import sys
5 8 from typing import List
6 9  
  10 +# DJANGO imports
7 11 from django.contrib.auth.models import AbstractUser
8 12 from django.db import models
9 13 from django.db.models import Q
10 14 from django.core.validators import MaxValueValidator, MinValueValidator
11 15 from model_utils import Choices
12 16  
  17 +# Project imports
13 18 # DeviceCommand is used by class Command
14   -import sys
15 19 sys.path.append("../../..")
16 20 from src.device_controller.abstract_component.device_controller import DeviceCommand
17 21  
... ... @@ -161,6 +165,9 @@ class Company(models.Model):
161 165 """
162 166  
163 167  
  168 +def printd(*args, **kwargs):
  169 + if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
  170 +
164 171 # ---
165 172 # --- Utility functions
166 173 # ---
... ... @@ -521,7 +528,7 @@ class Command(models.Model):
521 528  
522 529 @classmethod
523 530 def delete_commands_with_running_status_for_agent(cls, agent_name):
524   - print("Delete (false) 'running' command if exists:")
  531 + printd("Delete (false) 'running' commands if exists:")
525 532 running_commands = cls.objects.filter(
526 533 # only commands for agent agent_name
527 534 recipient = agent_name,
... ... @@ -533,7 +540,7 @@ class Command(models.Model):
533 540 if running_commands:
534 541 Command.show_commands(running_commands)
535 542 running_commands.delete()
536   - else: print("<None>")
  543 + else: printd("<None>")
537 544  
538 545 @classmethod
539 546 def delete_pending_commands_for_agent(cls, agent_name):
... ... @@ -545,7 +552,7 @@ class Command(models.Model):
545 552 - agentB will then delete the command just sent by agentA
546 553 - agentA will check regularly the status of its sent command, and this will crash as this command exists no more !!
547 554 """
548   - print("Delete all pending command(s) if exists (except very recent ones):")
  555 + printd("Delete all pending command(s) if exists (except very recent ones):")
549 556 now_minus_2sec = datetime.utcnow().astimezone() - timedelta(seconds = 2)
550 557 #print("now_minus_2sec", now_minus_2sec)
551 558 pending_commands = cls.objects.filter(
... ... @@ -559,7 +566,7 @@ class Command(models.Model):
559 566 if pending_commands:
560 567 Command.show_commands(pending_commands)
561 568 pending_commands.delete()
562   - else: print("<None>")
  569 + else: printd("<None>")
563 570  
564 571 @classmethod
565 572 def get_pending_and_running_commands_for_agent(cls, agent_name):
... ... @@ -608,7 +615,7 @@ class Command(models.Model):
608 615 NB: datetime.utcnow() is equivalent to datetime.now(timezone.utc)
609 616 """
610 617  
611   - print(f"(Looking for commands sent to me that are not executing and older than {cls.COMMANDS_PEREMPTION_HOURS} hour(s))")
  618 + printd(f"(Looking for commands sent to me that are not executing and older than {cls.COMMANDS_PEREMPTION_HOURS} hour(s))")
612 619 #COMMAND_PEREMPTION_DATE_FROM_NOW = datetime.utcnow() - timedelta(hours = cls.COMMANDS_PEREMPTION_HOURS)
613 620 #print("peremption date", COMMAND_PEREMPTION_DATE_FROM_NOW)
614 621 old_commands = cls.objects.filter(
... ... @@ -620,21 +627,25 @@ class Command(models.Model):
620 627 state = cls.CMD_STATUS_CODES.CMD_RUNNING
621 628 )
622 629 if old_commands.exists():
623   - print("Found old commands to delete:")
  630 + printd("Found old commands to delete:")
624 631 #for cmd in old_commands: print(cmd)
625 632 cls.show_commands(old_commands)
626 633 old_commands.delete()
627 634 else:
628   - print("<None>")
  635 + printd("<None>")
629 636  
630 637 @classmethod
631 638 #def show_commands(cls, commands:models.query):
632   - def show_commands(cls, commands:list):
  639 + def show_commands(cls, commands:list, do_it:bool=False):
633 640 #def show_commands(cls, commands:List[Commmand]):
634 641 #if not commands.exists(): print("<No command>")
635 642 commands = list(commands)
636   - if len(commands) == 0: print("<No command>")
637   - for cmd in commands: print("-", cmd.name, cmd)
  643 + if len(commands) == 0:
  644 + if do_it: print("<None>")
  645 + else: printd("<None>")
  646 + for cmd in commands:
  647 + if do_it: print("-", cmd.name, cmd)
  648 + else: printd("-", cmd.name, cmd)
638 649  
639 650  
640 651 # -------------- Command INSTANCE METHODS --------------
... ... @@ -742,7 +753,7 @@ class Command(models.Model):
742 753 def is_expired(self):
743 754 #return (datetime.utcnow() - self.s_deposit_time) > timedelta(seconds = self.validity_duration)
744 755 elapsed_time = (datetime.utcnow().astimezone() - self.s_deposit_time)
745   - print("elapsed_time", elapsed_time)
  756 + printd("elapsed_time", elapsed_time)
746 757 return elapsed_time > timedelta(seconds = self.validity_duration)
747 758 """
748 759 elapsed_time = cmd.r_read_time - cmd.s_deposit_time
... ... @@ -770,7 +781,7 @@ class Command(models.Model):
770 781 self.save(update_fields=["r_read_time"])
771 782  
772 783 def set_as_processed(self):
773   - print(f"- Set command {self.name} as processed")
  784 + printd(f"- Set command {self.name} as processed")
774 785 self.set_state_to(self.CMD_STATUS_CODES.CMD_EXECUTED)
775 786 #print(self)
776 787 """
... ... @@ -792,12 +803,12 @@ class Command(models.Model):
792 803 self.set_state_to(self.CMD_STATUS_CODES.CMD_SKIPPED)
793 804  
794 805 def set_as_killed_by(self, author_agent:str):
795   - print(f"- Set command {self.name} as killed")
  806 + printd(f"- Set command {self.name} as killed")
796 807 #print(f"- Set this command as killed: {self}")
797 808 self.set_state_to(self.CMD_STATUS_CODES.CMD_KILLED, author_agent)
798 809  
799 810 def set_as_running(self):
800   - print(f"- Set command {self.name} as running")
  811 + printd(f"- Set command {self.name} as running")
801 812 self.set_state_to(self.CMD_STATUS_CODES.CMD_RUNNING)
802 813 '''
803 814 def set_as_executed(self):
... ...
src/device_controller/abstract_component/detector_sensor.py
... ... @@ -22,7 +22,7 @@ import sys
22 22 #from device_controller.abstract_component.base import *
23 23 #sys.path.append("../..")
24 24 #from device_controller.abstract_component.base import *
25   -from device_controller.abstract_component.device_controller import DeviceController
  25 +from device_controller.abstract_component.device_controller import printd, DeviceController
26 26  
27 27  
28 28  
... ... @@ -54,7 +54,7 @@ class DC_DetectorSensor(DeviceController):
54 54 :param device_port: server port
55 55 :param PROTOCOL: "UDP" or "TCP"
56 56 '''
57   - print("IN DeviceControllerFilterSelector")
  57 + printd("IN DeviceControllerFilterSelector")
58 58 #self._my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
59 59 my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
60 60 #super().__init__(device_host, device_port, PROTOCOL, buffer_size, DEBUG, device_sim)
... ...
src/device_controller/abstract_component/detector_shutter.py
... ... @@ -22,7 +22,7 @@ import sys
22 22 #from device_controller.abstract_component.base import *
23 23 #sys.path.append("../..")
24 24 #from device_controller.abstract_component.base import *
25   -from device_controller.abstract_component.device_controller import DeviceController
  25 +from device_controller.abstract_component.device_controller import printd, DeviceController
26 26  
27 27  
28 28 #class SocketClientTelescopeAbstract(SocketClientAbstract):
... ... @@ -50,7 +50,7 @@ class DC_DetectorShutter(DeviceController):
50 50 :param device_port: server port
51 51 :param PROTOCOL: "UDP" or "TCP"
52 52 '''
53   - print("IN DeviceControllerFilterSelector")
  53 + printd("IN DeviceControllerFilterSelector")
54 54 #self._my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
55 55 my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
56 56 #super().__init__(device_host, device_port, PROTOCOL, buffer_size, DEBUG, device_sim)
... ...
src/device_controller/abstract_component/device_controller.py
... ... @@ -53,7 +53,7 @@ TIMEOUT_RECEIVE = 10
53 53  
54 54  
55 55 def printd(*args, **kwargs):
56   - if os.environ.get('PYROS_DEBUG', '0')=='1': printd(*args, **kwargs)
  56 + if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
57 57  
58 58  
59 59 '''
... ... @@ -325,11 +325,11 @@ class Gen2NatCmds:
325 325 printd(f"\n{dcc_key} commands are:")
326 326 printd("- GET commands:")
327 327 #print (list(cmd.replace('_',' ') for cmd in self._gen2nat_cmds.keys() if cmd.startswith('get_')))
328   - print (list(cmd for cmd in d.keys() if cmd.startswith('get_')))
  328 + printd (list(cmd for cmd in d.keys() if cmd.startswith('get_')))
329 329 printd("- SET commands:")
330   - print (list(cmd for cmd in d.keys() if cmd.startswith('set_')))
  330 + printd (list(cmd for cmd in d.keys() if cmd.startswith('set_')))
331 331 printd("- DO commands:")
332   - print (list(cmd for cmd in d.keys() if cmd.startswith('do_')))
  332 + printd (list(cmd for cmd in d.keys() if cmd.startswith('do_')))
333 333  
334 334  
335 335  
... ... @@ -450,7 +450,7 @@ class DeviceController():
450 450 self.stamp_current = None
451 451  
452 452 #self.DEBUG_MODE = DEBUG
453   - self.DEBUG_MODE = os.environ.get('PYROS_DEBUG', '0') == 1
  453 + self.DEBUG_MODE = os.environ.get('PYROS_DEBUG', '0') == '1'
454 454 set_logger(self.DEBUG_MODE)
455 455 log_d("Logger configured")
456 456  
... ... @@ -592,7 +592,7 @@ class DeviceController():
592 592 ##data = self.unformat_received_data(data_received)
593 593 data = self.uncap(self.stamp_current, data_received)
594 594 printd(f"(dc) ({self}) RECEIVED (useful data): {data}")
595   - log_i(f"(dc) ({self}) RECEIVED (useful data): {data}")
  595 + ##log_i(f"(dc) ({self}) RECEIVED (useful data): {data}")
596 596 return data
597 597 '''
598 598 def _receive_data(self):
... ... @@ -963,7 +963,7 @@ class DeviceController():
963 963 return self.send_native_cmd(request)
964 964  
965 965  
966   - # wrapper methods
  966 + # wrapper shortcut methods
967 967 def print_available_cmds(self): self._my_cmds.print_available_cmds()
968 968 def print_available_cmds_for_dcc(self, dcc_key): self._my_cmds.print_available_cmds_for_dcc(dcc_key)
969 969  
... ... @@ -1043,7 +1043,7 @@ class DeviceController():
1043 1043 #printd("(DC): My ("+type(self).__name__+") commands are:", self._my_cmds.get())
1044 1044 #printd("(DC): My ("+type(self).__name__+") commands are:", self._my_cmds.get())
1045 1045 self.tprintd("(DC): My ("+type(self).__name__+") commands are:")
1046   - pprint.pprint(self._my_cmds.get())
  1046 + if self.DEBUG_MODE: pprint.pprint(self._my_cmds.get())
1047 1047  
1048 1048 dcc, native_cmd_infos = self.get_dcc_and_native_cmd_for_generic(generic_cmd)
1049 1049 self.tprintd("native_cmd_infos", native_cmd_infos)
... ...
src/device_controller/abstract_component/filter_selector.py
... ... @@ -22,7 +22,7 @@ import sys
22 22 #from device_controller.abstract_component.base import *
23 23 #sys.path.append("../..")
24 24 #from device_controller.abstract_component.base import *
25   -from device_controller.abstract_component.device_controller import DeviceController
  25 +from device_controller.abstract_component.device_controller import printd, DeviceController
26 26  
27 27  
28 28 # Default timeouts
... ... @@ -62,7 +62,7 @@ class DC_FilterSelector(DeviceController):
62 62 :param device_port: server port
63 63 :param PROTOCOL: "UDP" or "TCP"
64 64 '''
65   - print("IN DC_FilterSelector")
  65 + printd("IN DC_FilterSelector")
66 66 #self._my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
67 67 my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
68 68 #super().__init__(device_host, device_port, PROTOCOL, buffer_size, DEBUG, device_sim)
... ...
src/device_controller/abstract_component/mount.py
... ... @@ -27,7 +27,7 @@ import src.core.celme as celme
27 27 ##from src_socket.client.socket_client_abstract import *
28 28 #from device_controller.abstract_component.device_controller import *
29 29 from device_controller.abstract_component.device_controller import (
30   - DeviceController, generic_cmd, GenericResult,
  30 + printd, DeviceController, generic_cmd, GenericResult,
31 31 UnexpectedCommandReturnCode, UnknownGenericCmdArgException, TimeoutException
32 32 )
33 33  
... ... @@ -61,6 +61,7 @@ class c(Enum):
61 61  
62 62  
63 63  
  64 +
64 65 class Position():
65 66 x = 0
66 67 y = 0
... ... @@ -131,16 +132,16 @@ class DC_Mount(DeviceController):
131 132 :param device_port: server port
132 133 :param CHANNEL: "UDP" or "TCP"
133 134 '''
134   - print("IN DC_Mount")
  135 + printd("IN DC_Mount")
135 136  
136 137 # _my_gen2nat_cmds = GEN2NAT_CMDS + gen2nat_cmds
137 138 #self._my_gen2nat_cmds = self.GEN2NAT_CMDS
138 139 #self._my_gen2nat_cmds.update(gen2nat_cmds)
139   - #print("(mount 1) my cmds (before):", self.GEN2NAT_CMDS)
140   - #print("(mount 2) given cmds (before):", gen2nat_cmds)
  140 + #printd("(mount 1) my cmds (before):", self.GEN2NAT_CMDS)
  141 + #printd("(mount 2) given cmds (before):", gen2nat_cmds)
141 142 ##self._my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
142 143 my_gen2nat_cmds = { **self.GEN2NAT_CMDS, **gen2nat_cmds }
143   - #print("(mount 3) my cmds (after):", self._my_gen2nat_cmds)
  144 + #printd("(mount 3) my cmds (after):", self._my_gen2nat_cmds)
144 145  
145 146 ##super().__init__(device_host, device_port, channel, buffer_size, DEBUG, device_sim)
146 147 super().__init__(device_host, device_port, channel, buffer_size, protoc=protoc, gen2nat_cmds=my_gen2nat_cmds, device_sim=device_sim, DEBUG=DEBUG)
... ... @@ -291,9 +292,9 @@ class DC_Mount(DeviceController):
291 292 # MACRO generic command
292 293 def do_init(self):
293 294  
294   - print("...STARTING TELESCOPE INITIALIZATION...")
  295 + printd("...STARTING TELESCOPE INITIALIZATION...")
295 296 time.sleep(1)
296   - print("...TELESCOPE INITIALIZATION ENDED")
  297 + printd("...TELESCOPE INITIALIZATION ENDED")
297 298 return GenericResult("OK")
298 299  
299 300 '''
... ... @@ -341,13 +342,13 @@ class DC_Mount(DeviceController):
341 342 => :SG{+-}hh#
342 343 '''
343 344 res = self.get_timezone()
344   - print("Current timezone is", res)
  345 + printd("Current timezone is", res)
345 346 res = self.set_timezone('+00')
346 347 #if res != '1': raise UnexpectedCommandReturnCode(res)
347 348 if not res.ok: raise UnexpectedCommandReturnCode(res)
348 349 res = self.get_timezone()
349 350 if res.txt != '+00': raise UnexpectedCommandReturnCode(res)
350   - print("NEW timezone set is", res)
  351 + printd("NEW timezone set is", res)
351 352  
352 353  
353 354 '''
... ... @@ -362,12 +363,12 @@ class DC_Mount(DeviceController):
362 363 1Updating planetary data#<24 blanks>#
363 364 '''
364 365 res = self.get_date()
365   - print("Current date is", res)
  366 + printd("Current date is", res)
366 367 # format is 2018-09-26T17:50:21
367 368 d = self.get_utc_date()
368 369 # format to mm/dd/yy
369 370 now_utc_mm_dd_yy = d[5:7] + '/' + d[8:10] + '/' + d[2:4]
370   - #print("date is", now_utc_mm_dd_yy)
  371 + #printd("date is", now_utc_mm_dd_yy)
371 372 res = self.set_date(now_utc_mm_dd_yy)
372 373 #res = self.set_DATE(self.get_utc_date())
373 374 #if res[0] != '1': raise UnexpectedCommandReturnCode(res)
... ... @@ -375,7 +376,7 @@ class DC_Mount(DeviceController):
375 376 if not res.ok: raise UnexpectedCommandReturnCode(res)
376 377 res = self.get_date()
377 378 if res.txt != now_utc_mm_dd_yy: raise UnexpectedCommandReturnCode(res)
378   - print("NEW DATE set is", res)
  379 + printd("NEW DATE set is", res)
379 380  
380 381 '''
381 382 c) set TIME
... ... @@ -384,15 +385,15 @@ class DC_Mount(DeviceController):
384 385 :SL<hh>:<mm>:<ss>#
385 386 '''
386 387 res = self.get_time()
387   - print("Current time is", res)
  388 + printd("Current time is", res)
388 389 _,now_utc_hh_mm_ss = d.split('T')
389   - #print("time is", now_utc_hh_mm_ss[:5])
  390 + #printd("time is", now_utc_hh_mm_ss[:5])
390 391 res = self.set_time(now_utc_hh_mm_ss)
391 392 #if res != '1': raise UnexpectedCommandReturnCode(res)
392 393 if not res.ok: raise UnexpectedCommandReturnCode(res)
393 394 res = self.get_time()
394 395 if res.txt[:5] != now_utc_hh_mm_ss[:5]: raise UnexpectedCommandReturnCode(res)
395   - print("NEW TIME set is", res)
  396 + printd("NEW TIME set is", res)
396 397  
397 398  
398 399 '''
... ... @@ -413,7 +414,7 @@ class DC_Mount(DeviceController):
413 414 '''
414 415 # TELE format is -002ยฐ02 (I convert it to -002:02)
415 416 res = self.get_long()
416   - print("Current longitude is", res)
  417 + printd("Current longitude is", res)
417 418  
418 419 # CELME format is -002:02:15
419 420 res = self.get_celme_longitude("-2.0375")
... ... @@ -421,7 +422,7 @@ class DC_Mount(DeviceController):
421 422 #res_ddd_mm = res[:-3].replace(':','*')
422 423 #res_ddd_mm = '-002:03'
423 424  
424   - #print("celme longitude is", res)
  425 + #printd("celme longitude is", res)
425 426 ddd,mm,ss = res.split(':')
426 427 #dddmm = '-002*03'
427 428 res = self.set_long(ddd+'*'+mm)
... ... @@ -429,7 +430,7 @@ class DC_Mount(DeviceController):
429 430 if not res.ok: raise UnexpectedCommandReturnCode(res)
430 431 res = self.get_long()
431 432 if res.txt != res_ddd_mm: raise UnexpectedCommandReturnCode(res_ddd_mm, res.txt)
432   - print("NEW longitude set is", res)
  433 + printd("NEW longitude set is", res)
433 434  
434 435 '''
435 436 b) set Latitude
... ... @@ -439,16 +440,16 @@ class DC_Mount(DeviceController):
439 440 '''
440 441 # TELE format is +43ยฐ38 (I convert it to +43:38)
441 442 res = self.get_lat()
442   - print("Current latitude is", res)
  443 + printd("Current latitude is", res)
443 444  
444 445 # CELME format is +43:38:15
445 446 res = self.get_celme_latitude("+43.6443")
446 447 res_dd_mm = res[:-3]
447 448 #res_dd_mm = res[:-3].replace(':','*')
448   - print("res is", res)
  449 + printd("res is", res)
449 450 #res_dd_mm = '+43:50'
450 451  
451   - #print("celme longitude is", res)
  452 + #printd("celme longitude is", res)
452 453 dd,mm,ss = res.split(':')
453 454 ddmm = dd+'*'+mm
454 455 #ddmm = '+43*50'
... ... @@ -457,7 +458,7 @@ class DC_Mount(DeviceController):
457 458 if not res.ok: raise UnexpectedCommandReturnCode(res)
458 459 res = self.get_lat()
459 460 if res.txt != res_dd_mm: raise UnexpectedCommandReturnCode(res_dd_mm,res.txt)
460   - print("NEW latitude set is", res)
  461 + printd("NEW latitude set is", res)
461 462  
462 463  
463 464 '''
... ... @@ -487,17 +488,17 @@ class DC_Mount(DeviceController):
487 488 def do_goto(self, ra, dec, speed_rate=None):
488 489  
489 490 # TODO: remove
490   - print("...Starting GOTO...")
  491 + printd("...Starting GOTO...")
491 492 time.sleep(3)
492 493 radec = self.get_radec()
493   - print("...GOTO ended OK")
  494 + printd("...GOTO ended OK")
494 495 return GenericResult("OK")
495 496  
496 497 # 1) set speed
497 498 if speed_rate : self.set_speed(speed_rate)
498 499  
499 500 radec = self.get_radec()
500   - print("Current position is", radec)
  501 + printd("Current position is", radec)
501 502  
502 503 # 2) set RA-DEC
503 504 '''
... ... @@ -526,12 +527,12 @@ class DC_Mount(DeviceController):
526 527 while vel != 'T':
527 528 v = self.get_vel()
528 529 vel = v.txt
529   - print("Velocity is", v)
  530 + printd("Velocity is", v)
530 531 time.sleep(2)
531 532  
532 533 time.sleep(2)
533 534 radec= self.get_radec()
534   - print("Current position is", radec)
  535 + printd("Current position is", radec)
535 536  
536 537 return GenericResult("OK")
537 538  
... ... @@ -582,14 +583,14 @@ if __name__ == &quot;__main__&quot;:
582 583 #data_to_send = bytes(data + "\n", "utf-8")
583 584 tsock.send_data(data)
584 585 #mysock.sendto("%s" % data, (HOST, PORT))
585   - #print("Sent: {}".format(data))
  586 + #printd("Sent: {}".format(data))
586 587  
587 588 # 2) RECEIVE REPLY data from server
588 589 data_received = tsock.receive_data()
589 590 #reponse, adr = mysock.recvfrom(buf)
590   - #print("Received: {}".format(data_received))
591   - #print("Useful data received: {}".format(data_useful))
592   - print('\n')
  591 + #printd("Received: {}".format(data_received))
  592 + #printd("Useful data received: {}".format(data_useful))
  593 + printd('\n')
593 594  
594 595 #tsock.close()
595 596 '''
596 597 \ No newline at end of file
... ...
src/device_controller/channels/client_channel.py
... ... @@ -7,6 +7,7 @@ To be used as a base class (interface) for any concrete socket client class
7 7  
8 8  
9 9 # Standard library imports
  10 +import os
10 11  
11 12 # Third party imports
12 13 # None
... ... @@ -15,6 +16,10 @@ To be used as a base class (interface) for any concrete socket client class
15 16 from device_controller.logs import *
16 17  
17 18  
  19 +def printd(*args, **kwargs):
  20 + if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
  21 +
  22 +
18 23  
19 24 ##class SocketClientAbstract():
20 25 class ClientChannel():
... ... @@ -38,8 +43,9 @@ class ClientChannel():
38 43 # Logger configuration
39 44 #self.set_logger()
40 45 ##set_logger(DEBUG)
41   - log_d("\n**************************")
42   - log_d("Client CHANNEL instanciated")
  46 + printd("\n**************************")
  47 + ##log_d("Client CHANNEL instanciated")
  48 + printd("Client CHANNEL instanciated")
43 49  
44 50  
45 51  
... ... @@ -48,7 +54,7 @@ class ClientChannel():
48 54 return self
49 55 def __exit__(self, type, value, traceback):
50 56 self.close()
51   - #log_d("Client channel killed")
  57 + #printd("Client channel killed")
52 58 print("Client channel killed")
53 59  
54 60  
... ... @@ -79,8 +85,8 @@ class ClientChannel():
79 85 def receive_data(self)->str:
80 86 data_received = self._receive_data()
81 87 ##data_received_bytes = self.mysock.recv(self.buf)
82   - #log_d("Received (all data): {}".format(data_received))
83   - #log_d("data in bytes: "+str(bytes(data_received, "utf-8")))
  88 + #printd("Received (all data): {}".format(data_received))
  89 + #printd("data in bytes: "+str(bytes(data_received, "utf-8")))
84 90 ##data_received_uncaped = self.uncap_received_data(data_received)
85 91 #log_i("RECEIVED (useful data): {}".format(data_received))
86 92 return data_received
... ... @@ -89,7 +95,7 @@ class ClientChannel():
89 95 pass
90 96 '''
91 97 data_received = self.mysock.recv(self.buf)
92   - #log_d("data type is "+str(type(data_received)))
  98 + #printd("data type is "+str(type(data_received)))
93 99 log_i(f"RECEIVED (ALL BYTES): {data_received}")
94 100 #return str(data_received, "utf-8")
95 101 return data_received
... ...
src/device_controller/channels/client_channel_socket.py
... ... @@ -86,7 +86,7 @@ class ClientChannelSocket(ClientChannel):
86 86 #@override
87 87 def _connect_to_server(self):
88 88 if self.PROTOCOL=="SOCKET-TCP": self.mysock.connect((self.HOST, self.PORT))
89   - print(f"Ready to send commands to HOST {self.HOST} on PORT {self.PORT} \n")
  89 + printd(f"Ready to send commands to HOST {self.HOST} on PORT {self.PORT} \n")
90 90  
91 91  
92 92 # Close socket
... ... @@ -108,8 +108,11 @@ class ClientChannelSocket(ClientChannel):
108 108 else:
109 109 # SOCKET-UDP
110 110 nb_bytes_sent = self.mysock.sendto(data_to_send_bytes, (self.HOST, self.PORT))
111   - log_i(f'(channel sock) Sent: {data_to_send_bytes}')
112   - log_i(f"(channel sock) Sent {nb_bytes_sent} bytes")
  111 + ##log_i(f'(channel sock) Sent: {data_to_send_bytes}')
  112 + ##log_i(f"(channel sock) Sent {nb_bytes_sent} bytes")
  113 + ##log_i(f"(channel sock) Sent {nb_bytes_sent} bytes ; mesg sent is: ", data_to_send_bytes)
  114 + ##log_i("(channel sock) Sent ",nb_bytes_sent, "bytes ; mesg sent is: ", data_to_send_bytes)
  115 + printd("(channel sock) Sent ",nb_bytes_sent, "bytes ; mesg sent is: ", data_to_send_bytes)
113 116  
114 117 #@override
115 118 def _receive_data(self)->str:
... ... @@ -119,8 +122,9 @@ class ClientChannelSocket(ClientChannel):
119 122 # so, replace it by ':' (b'\x3A')
120 123 if b'\xdf' in data_received_bytes:
121 124 data_received_bytes = data_received_bytes.replace(b'\xdf', b'\x3A')
122   - print(f"(channel sock) RECEIVED (ALL BYTES...): {data_received_bytes}")
123   - log_i(f"(channel sock) ({self}) RECEIVED (ALL BYTES...): {data_received_bytes}")
  125 + printd(f"(channel sock) RECEIVED (ALL BYTES...): {data_received_bytes}")
  126 + ##log_i(f"(channel sock) ({self}) RECEIVED (ALL BYTES...): {data_received_bytes}")
  127 + printd(f"(channel sock) ({self}) RECEIVED (ALL BYTES...): {data_received_bytes}")
124 128  
125 129 data_received = data_received_bytes.decode()
126 130 #log_d("data type is "+str(type(data_received)))
... ...
src/device_controller/channels/server_udp_or_tcp.py
... ... @@ -17,6 +17,8 @@ import sys
17 17  
18 18 # Local application imports
19 19 # None
  20 +from .client_channel import printd
  21 +
20 22 '''
21 23 sys.path.append('..')
22 24 from device_controller.abstract_component.device_simulator import getc, getp
... ... @@ -25,7 +27,7 @@ from device_controller.abstract_component.device_simulator import getc, getp
25 27 # Very BASIC implementation
26 28 def make_answer_for_request_CMD_TO_UPPER(request_bytes):
27 29 #raise NotImplementedError
28   - print("(SIM serv) Request received is", request_bytes)
  30 + printd("(SIM serv) Request received is", request_bytes)
29 31  
30 32 # Convert to string
31 33 request = request_bytes.decode("utf-8")
... ... @@ -38,7 +40,7 @@ def make_answer_for_request_CMD_TO_UPPER(request_bytes):
38 40 #stamp = request[0:STAMP_LENGTH]
39 41 #command = request[STAMP_LENGTH:]
40 42 command = request
41   - print("(SIM serv) Command received is", repr(command))
  43 + printd("(SIM serv) Command received is", repr(command))
42 44  
43 45 answer = 'ANSWER TO '+command.upper()
44 46 #if command == ':GR#': answer = "15:01:49"
... ... @@ -48,8 +50,8 @@ def make_answer_for_request_CMD_TO_UPPER(request_bytes):
48 50  
49 51 #full_answer_in_bytes = bytes(stamp + answer + '#' + TERMINATOR, "utf-8")
50 52 full_answer_in_bytes = bytes(answer, "utf-8")
51   - #print("request str upper is", str(request).upper())
52   - print("(SIM serv) Answer sent is", full_answer_in_bytes)
  53 + #printd("request str upper is", str(request).upper())
  54 + printd("(SIM serv) Answer sent is", full_answer_in_bytes)
53 55 return full_answer_in_bytes
54 56  
55 57  
... ... @@ -84,8 +86,8 @@ def get_SocketServer_UDP_TCP(myhost:str=&quot;localhost&quot;, myport:int=11110, PROTOCOL:
84 86 # For UDP, self.request consists of a pair of data and client socket
85 87 data_rcv = self.request[0].strip()
86 88 socket_client = self.request[1]
87   - print("(SIM serv) {} wrote:".format(self.client_address[0]))
88   - print("(SIM serv)", data_rcv)
  89 + printd("(SIM serv) {} wrote:".format(self.client_address[0]))
  90 + printd("(SIM serv)", data_rcv)
89 91  
90 92 # Send back the same data, but upper-cased
91 93 # - TCP
... ... @@ -125,9 +127,9 @@ def get_SocketServer_UDP_TCP(myhost:str=&quot;localhost&quot;, myport:int=11110, PROTOCOL:
125 127 #data_received = self.request.recv(1024)
126 128 data_received = self.rfile.readline().strip() # data is "bytes" type
127 129 data_useful = self.get_useful_data(data_received)
128   - #print("data type is", type(data))
129   - #print("\nFrom {}, received: {}".format(self.client_address[0], data_useful))
130   - print(f"\n(SIM server_udp_or_tcp) From {self.client_address[0]}, received: {data_useful}\n")
  130 + #printd("data type is", type(data))
  131 + #printd("\nFrom {}, received: {}".format(self.client_address[0], data_useful))
  132 + printd(f"\n(SIM server_udp_or_tcp) From {self.client_address[0]}, received: {data_useful}\n")
131 133  
132 134 # 2) SEND REPLY to client
133 135 # Likewise, self.wfile is a file-like object used to write back to the client
... ...
src/device_controller/concrete_component/gemini/proof_of_concept_for_logging/proof_of_concept_for_logging.py 0 โ†’ 100644
... ... @@ -0,0 +1,83 @@
  1 +
  2 +import logging
  3 +from logging.handlers import SMTPHandler
  4 +
  5 +# https://docs.python.org/3/library/logging.html#logging.getLogger
  6 +#logger = logging.getLogger(__name__)
  7 +logger = logging.getLogger('pyros_logger')
  8 +# If not set, default level is NOTSET (all messages are logged)
  9 +# The defined levels, in order of increasing severity : DEBUG, INFO, WARNING, ERROR, CRITICAL
  10 +#logger.setLevel(logging.DEBUG)
  11 +
  12 +# Create handlers
  13 +
  14 +# Console should print ALL messages (starting from lower level DEBUG)
  15 +c_handler = logging.StreamHandler()
  16 +c_handler.setLevel(logging.DEBUG)
  17 +c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
  18 +c_handler.setFormatter(c_format)
  19 +
  20 +# Log File should contain ONLY messages starting from level WARNING (ERROR ?)
  21 +f_handler = logging.FileHandler('file.log')
  22 +f_handler.setLevel(logging.WARNING)
  23 +# Create formatter and add it to handler
  24 +#f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  25 +f_format = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s : %(lineno)s - %(message)s')
  26 +f_handler.setFormatter(f_format)
  27 +
  28 +# DB should contain ONLY messages starting from level ERROR
  29 +# TODO:
  30 +
  31 +# Email should be sent ONLY for messages starting from level CRITICAL
  32 +# http://sametmax.com/envoi-dun-email-par-logging-en-cas-de-plantage-dun-script-python-ou-comment-faire-bouffer-uxe9-a-smtphandler/
  33 +# TODO: a ameliorer avec article ci-dessus pour UNICODE
  34 +m_handler = SMTPHandler(
  35 + # Host et port
  36 + ('SMTP.GMAIL.COM', 587),
  37 + # From
  38 + "MOI@GMAIL.COM",
  39 + # To (liste)
  40 + ["QUELQU.UN@QUELQUE.PART"],
  41 + # Sujet du message
  42 + "Erreur critique dans module MMM",
  43 + # pour l'authentification
  44 + credentials = ("MONEMAIL@GMAIL.COM", "MONSUPERPASSWORD"),
  45 + secure = ()
  46 +)
  47 +m_handler.setLevel(logging.WARNING)
  48 +m_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  49 +m_handler.setFormatter(m_format)
  50 +
  51 +
  52 +
  53 +
  54 +# Add handlers to the logger
  55 +logger.addHandler(c_handler)
  56 +logger.addHandler(f_handler)
  57 +# TODO:
  58 +##logger.addHandler(db_handler)
  59 +##logger.addHandler(m_handler)
  60 +
  61 +def do_logs():
  62 + logger.debug('This is a debug msg')
  63 + logger.info('This is a info msg')
  64 + logger.warning('This is a warning')
  65 + logger.error('This is an error')
  66 + logger.critical('This is a critical msg')
  67 +
  68 +
  69 +# USE it
  70 +
  71 +# logger.debug(), info(), warning(), error(), critical()
  72 +
  73 +print("\nlevel is DEBUG:")
  74 +logger.setLevel(logging.DEBUG)
  75 +do_logs()
  76 +
  77 +print("\nlevel is INFO:")
  78 +logger.setLevel(logging.INFO)
  79 +do_logs()
  80 +
  81 +print("\nlevel is CRITICAL:")
  82 +logger.setLevel(logging.CRITICAL)
  83 +do_logs()
0 84 \ No newline at end of file
... ...
src/device_controller/logs.py
... ... @@ -28,7 +28,7 @@ def log_c(msg:str, *args, **kwargs): logger.critical(msg, *args, **kwargs)
28 28  
29 29  
30 30 #def set_logger(self):
31   -def set_logger(DEBUG=False):
  31 +def set_logger(DEBUG_MODE:bool=False):
32 32 global logger
33 33 '''
34 34 # Logger configuration
... ... @@ -41,26 +41,29 @@ def set_logger(DEBUG=False):
41 41 logging.basicConfig(level=logging.DEBUG, filename='client.log', filemode='a', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
42 42 logging.debug("Client instanciated")
43 43 '''
44   -
  44 +
45 45 # Advanced configuration
46 46 logger = logging.getLogger(__name__)
47   - # Absolument necessaire, sinon rien ne marche !!!
48   - logger.setLevel(logging.DEBUG)
49   -
  47 + log_level = logging.DEBUG if DEBUG_MODE else logging.WARNING
  48 + logger.setLevel(log_level)
  49 +
50 50 # Create handlers for writing to console and file
51 51 c_handler = logging.StreamHandler()
52 52 f_handler = logging.FileHandler('client.log')
53   -
  53 +
54 54 # Set level for each handler
55 55 # DEBUG < INFO < WARNING < ERROR < CRITICAL
56   - #if self.DEBUG:
57   - if DEBUG:
  56 + c_handler.setLevel(logging.DEBUG)
  57 + f_handler.setLevel(logging.WARNING)
  58 + '''
  59 + if DEBUG_MODE:
58 60 c_handler.setLevel(logging.DEBUG)
59 61 f_handler.setLevel(logging.DEBUG)
60 62 else:
61 63 c_handler.setLevel(logging.INFO)
62 64 f_handler.setLevel(logging.INFO)
63   -
  65 + '''
  66 +
64 67 # Set format for each handler
65 68 #c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
66 69 c_format = logging.Formatter('(%(name)s): %(message)s')
... ...