#!/usr/bin/env python3 import sys ##import utils.Logger as L import time ##from .Agent import Agent sys.path.append("..") from agent.Agent import Agent, extract_parameters from common.models import AgentDeviceTelescopeStatus, get_or_create_unique_row_from_model from devices_controller.telescope_controller_gemini import TelescopeControllerGEMINI ##log = L.setupLogger("AgentXTaskLogger", "AgentX") class AgentDevice(Agent): _agent_device_telescope_status = None # FOR TEST ONLY # Run this agent in simulator mode SIMULATOR_MODE = False # Run the assertion tests at the end SIMULATOR_WITH_TEST = False #SIMULATOR_MAX_DURATION_SEC = None SIMULATOR_MAX_DURATION_SEC = 100 # Who should I send commands to ? #SIMULATOR_COMMANDS_DEST = "myself" SIMULATOR_COMMANDS_DEST = "AgentB" # Scenario to be executed SIMULATOR_COMMANDS_LIST = [ # Ask receiver to delete all its previous commands "flush_commands", "go_active", # Because of this command, the receiver agent : # - will no more send any new command # - will only execute "generic" commands (and not the "specific" ones) "go_idle", # Not executed (skipped) because receiver agent is now "idle" #"specific0", # Because of this command, the receiver agent # will now be able to send new commands "go_active", # Executed because recipient agent is now "active" "specific1", # should abort previous command (specific1) "abort", # Executed completely because no abort "specific2", # fully executed, result is 7 "eval 4+3", "go_idle", "exit", ] """ ================================================================= FUNCTIONS RUN INSIDE MAIN THREAD ================================================================= """ # @override def __init__(self, name:str=None, config_filename=None, RUN_IN_THREAD=True, device_controller=TelescopeControllerGEMINI): if name is None: name = self.__class__.__name__ super().__init__(name, config_filename, RUN_IN_THREAD) # Initialize the device table status # If table is empty, create a default 1st row self._agent_device_telescope_status = get_or_create_unique_row_from_model(AgentDeviceTelescopeStatus) """ if not AgentDeviceTelescopeStatus.objects.exists(): print("CREATE first row") self._agent_device_telescope_status = AgentDeviceTelescopeStatus.objects.create(id=1) # Get 1st row (will be updated at each iteration by routine_process() with current device status) print("GET first row") self._agent_device_telescope_status = AgentDeviceTelescopeStatus.objects.get(id=1) """ # Initialize the device socket # Port local AK 8085 = redirigé sur l’IP du tele 192.168.0.12 sur port 11110 HOST, PORT = "82.64.28.71", 11110 #HOST, PORT = "localhost", 11110 self.tele_ctrl = TelescopeControllerGEMINI(HOST, PORT, True) self._log.print(f"init done for {name}") # @override def init(self): super().init() # --- Set the mode according the startmode value ##agent_alias = self.__class__.__name__ ##self.set_mode_from_config(agent_alias) # Device socket init # (optional) Only useful for TCP (does nothing for UDP) self.tele_ctrl._connect_to_device() self.tele_ctrl.print_available_commands() # Telescope (long) init # TODO: ''' # @override def load_config(self): super().load_config() ''' ''' # @override def update_survey(self): super().update_survey() ''' ''' # @override def get_next_command(self): return super().get_next_command() ''' # @override def do_log(self): super().do_log() # @override def routine_process(self): self.print("ROUTINE PROCESS START: reading my dedicated device status information and storing it in DB)") self.print("...") cmd="get date" res = self.tele_ctrl.execute_cmd(cmd) print("result is", str(res)) if res.ok: print("OK") time.sleep(1) cmd="get time" res = self.tele_ctrl.execute_cmd(cmd) print("result is", str(res)) if res.ok: print("OK") time.sleep(1) cmd="get radec" res = self.tele_ctrl.execute_cmd(cmd) print("result is", str(res)) myradec = str(res) if res.ok: print("OK") time.sleep(1) # Save current device status to DB #AgentDeviceTelescopeStatus.objects.create(radec=myradec) self._agent_device_telescope_status.radec = myradec self._agent_device_telescope_status.save() #time.sleep(3) self.print("ROUTINE PROCESS END") # @override def kill_running_specific_cmd_if_exists(self, abort_sender): super().kill_running_specific_cmd_if_exists(abort_sender) print("Close telescope socket") self.tele_ctrl.close() # @override def specific_process(self, cmd): cmd.set_read_time() cmd.set_as_running() res = self.tele_ctrl.execute_cmd(cmd.name) cmd.set_result(str(res)) print("result is", str(res)) if res.ok: print("OK") cmd.set_as_processed() time.sleep(1) """ ================================================================= FUNCTIONS RUN INSIDE A SUB-THREAD (OR A PROCESS) (thread_*()) ================================================================= """ # Define your own command step(s) here def cmd_step1(self, step:int): cmd = self._current_specific_cmd cmd.result = f"in step #{step}/{self._thread_total_steps_number}" cmd.save() """ if self.RUN_IN_THREAD: print("(save from thread)") cmd.save() else: #@transaction.atomic print("(save from process)") with transaction.atomic(): cmd.save() #Command.objects.select_for_update() """ def cmd_step2(self, step:int): self.cmd_step1(step) def cmd_step3(self, step:int): self.cmd_step1(step) def cmd_step4(self, step:int): self.cmd_step1(step) """ # @override def thread_exec_specific_cmd_step(self, step:int, sleep_time:float=1.0): self.thread_stop_if_asked() cmd = self._current_specific_cmd print(f">>>>> Thread (cmd {cmd.name}): step #{step}/5") self.sleep(sleep_time) """ ''' # @override def exec_specific_cmd_start(self, cmd:Command, from_thread=True): super().exec_specific_cmd_start(cmd, from_thread) ''' # @override def thread_exec_specific_cmd_main(self): # This is optional self.thread_set_total_steps_number(5) # HERE, write your own scenario # scenario OK self.thread_exec_specific_cmd_step(1, self.cmd_step1, 1) self.thread_exec_specific_cmd_step(2, self.cmd_step2, 3) self.thread_exec_specific_cmd_step(3, self.cmd_step1, 5) self.thread_exec_specific_cmd_step(4, self.cmd_step3, 10) self.thread_exec_specific_cmd_step(5, self.cmd_step1, 4) # ... as many as you need """ autre scenario self.thread_exec_specific_cmd_step(1, self.cmd_step1, 1) self.thread_exec_specific_cmd_step(2, self.cmd_step2, 2) self.thread_exec_specific_cmd_step(3, self.cmd_step1, 2) self.thread_exec_specific_cmd_step(4, self.cmd_step3, 2) self.thread_exec_specific_cmd_step(5, self.cmd_step1, 3) """ ''' # @override def exec_specific_cmd_end(self, cmd:Command, from_thread=True): super().exec_specific_cmd_end(cmd, from_thread) ''' # @override def simulator_test_results_main(self, commands): nb_asserted = 0 for cmd in commands: if cmd.name == "flush_commands": assert cmd.is_executed() nb_asserted+=1 # 2 times if cmd.name == "go_active": assert cmd.is_executed() nb_asserted+=1 # 2 times if cmd.name == "go_idle": assert cmd.is_executed() nb_asserted+=1 """ if cmd.name == "specific0": assert cmd.is_skipped() assert cmd.result == "in step #5/5" nb_asserted+=1 """ if cmd.name == "specific1": assert cmd.is_killed() nb_asserted+=1 if cmd.name == "specific2": assert cmd.is_executed() assert cmd.result == "in step #5/5" nb_asserted+=1 if cmd.name == "eval 4+3": assert cmd.is_executed() assert cmd.get_result() == "7" nb_asserted+=1 if cmd.name in ("abort"): assert cmd.is_executed() nb_asserted+=1 if cmd.name in ("exit"): assert cmd.is_executed() nb_asserted+=1 return nb_asserted """ ================================================================= MAIN FUNCTION ================================================================= """ if __name__ == "__main__": # with thread RUN_IN_THREAD=True # with process #RUN_IN_THREAD=False TEST_MODE, configfile = extract_parameters() """ configfile = None # arg 1 : config file if len(sys.argv) == 2: configfile = sys.argv[1] """ #agent = AgentX() agent = AgentDevice("AgentDevice", configfile, RUN_IN_THREAD) agent.setSimulatorMode(TEST_MODE) print(agent) agent.run()