AgentMultiRequester.py 12 KB
#!/usr/bin/env python3


import sys
##import utils.Logger as L

##from .Agent import Agent
sys.path.append("..")
from agent.Agent import Agent, build_agent


##log = L.setupLogger("AgentXTaskLogger", "AgentX")



class AgentMultiRequester(Agent):

    # FOR TEST ONLY
    # Run this agent in simulator mode
    TEST_MODE = True
    # Run the assertion tests at the end
    TEST_WITH_FINAL_TEST = True
    #TEST_MAX_DURATION_SEC = None
    TEST_MAX_DURATION_SEC = 110
    # Who should I send commands to ?
    #TEST_COMMANDS_DEST = "myself"
    #TEST_COMMANDS_DEST = "AgentDeviceTelescopeGemini"

    # Scenario to be executed
    TEST_COMMANDS_LIST_GEMINI_AND_SBIG = [
        # Ask receiver to delete all its previous commands 
        'ad_mount do_flush_commands',
        ###'ad_filtersel do_flush_commands',
        ###'ad_shutter do_flush_commands',
        ###'ad_sensor do_flush_commands',

        #'ad_mount:go_active',
        'ad_mount set_state 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)
        ##'ad_mount:set_state:idle',

        # Because of this command, the receiver agent(s)
        # will now be able to send new commands
        ##'ad_mount:set_state:active',
        ##'ad_filtersel:set_state:active',
        ##'ad_shutter:set_state:active',
        ##'ad_sensor:set_state:active',

        'ad_mount do_init',
        ###'ad_filtersel do_init',
        ###'ad_shutter do_init',
        ###'ad_sensor do_init',

        'ad_mount do_goto_radec 15 20',
        ###'ad_filtersel do_goto 3',

        ##'ad_shutter:do_open',
        ##'ad_sensor:do_acquire:7000',
        ##'ad_shutter:do_close',

        ##'ad_sensor:do_shutdown'

        # Now stop all my device agent clients:
        'ad_mount do_exit',
        ###'ad_filtersel do_exit',
        ###'ad_shutter do_exit',
        ###'ad_sensor do_exit',
    ]


    TEST_COMMANDS_LIST_SBIG_ONLY = [
        # Ask receiver to delete all its previous commands 
        'ad_filtersel do_flush_commands',
        'ad_shutter do_flush_commands',
        'ad_sensor do_flush_commands',

        #'ad_mount:go_active',
        #'ad_filterselect set_state 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)
        ##'ad_mount:set_state:idle',

        # Because of this command, the receiver agent(s)
        # will now be able to send new commands
        ##'ad_mount:set_state:active',
        ##'ad_filterselect:set_state:active',
        ##'ad_shutter:set_state:active',
        ##'ad_sensor:set_state:active',

        #TODO: special cas à traiter
        'ad_sensor UNKNOWN_NATIVE_CMD',

        'ad_filtersel do_unimplemented',
        'ad_filtersel do_ad_sbig_specific1',
        'ad_filtersel do_ad_sbig_specific3_unimplemented',
        'ad_filtersel do_unknown',
        'ad_filtersel set_ad_sbig_specific2',
        'ad_shutter do_unimplemented',
        'ad_filtersel do_ad_sbig_specific4_unimplemented',
        'ad_sensor do_unimplemented',

        #'ad_mount do_init',
        #'ad_filtersel do_init',
        ##'ad_shutter:do_init',
        ##'ad_sensor:do_init',

        #'ad_mount do_goto_radec 15 20',
        'ad_filtersel do_goto 3',
        'ad_shutter do_open',
        'ad_sensor do_start_acq 7000',
        'ad_shutter do_close',

        ##'ad_sensor:do_shutdown'

        # Now stop all my device agent clients:
        #'ad_mount do_exit',
        'ad_filtersel do_exit',
        ##'ad_shutter:do_exit',
        ##'ad_sensor:do_exit',
    ]
    
    TEST_COMMANDS_LIST_BASIC_OLD = [
        # Ask receiver to delete all its previous commands 
        'AgentDeviceTelescope1:flush_commands',
        'AgentDeviceFilterSelector1:flush_commands',
        'AgentDeviceShutter1:flush_commands',
        'AgentDeviceSensor1:flush_commands',

        'AgentDeviceTelescope1: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)
        'AgentDeviceTelescope1: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
        'AgentDeviceTelescope1:go_active',

        # Executed because recipient agent is now "active"
        #"specific1",
        'AgentDeviceTelescope1:get radec',
        # should abort previous command (specific1)
        #"abort",

        # Executed completely because no abort
        #"specific2",

        # fully executed, result is 7
        #"eval 4+3",

        'AgentDeviceTelescope1:go_idle',

        # Now stop all my device agent clients:
        'AgentDeviceTelescope1:exit',
        'AgentDeviceFilterSelector1:exit',
        'AgentDeviceShutter1:exit',
        'AgentDeviceSensor1:exit',

    ]

    TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_SBIG_ONLY
    #TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_GEMINI_AND_SBIG



    """
    =================================================================
        FUNCTIONS RUN INSIDE MAIN THREAD
    =================================================================
    """

    # @override
    #def __init__(self, name:str=None, config_filename=None, RUN_IN_THREAD=True):
    def __init__(self, config_filename=None, RUN_IN_THREAD=True):
        ##if name is None: name = self.__class__.__name__
        #super().__init__(name, config_filename, RUN_IN_THREAD)
        super().__init__(config_filename, RUN_IN_THREAD)

        #TODO: : à mettre dans la config
        """
        'AgentDeviceTelescope1': 'AgentDeviceTelescopeGemini',
        'AgentDeviceFilterSelector1': 'AgentDeviceSBIG',
        'AgentDeviceShutter1': 'AgentDeviceSBIG',
        'AgentDeviceSensor1': 'AgentDeviceSBIG',
        """
        #'ad_filterselect': 'AgentDeviceSBIG.DeviceControllerFilterSelector',
        #'ad_mount':          'AgentDeviceTelescopeGemini.Telescope',
        #'ad_mount':          'AgentDeviceTelescopeGemini',
        '''
        self._my_client_agents = {
            'ad_mount':          'AgentDeviceTelescopeGemini.DC_Mount',
            'ad_filtersel':     'AgentDeviceSBIG.DC_FilterSelector',
            'ad_shutter':       'AgentDeviceSBIG.DC_DetectorShutter',
            'ad_sensor':        'AgentDeviceSBIG.DC_DetectorSensor',
        }
        '''
        self._my_client_agents = {
            'ad_mount':          'AgentDeviceTelescopeGemini.Mount',
            'ad_filtersel':     'AgentDeviceSBIG.FilterSelector',
            'ad_shutter':       'AgentDeviceSBIG.DetectorShutter',
            'ad_sensor':        'AgentDeviceSBIG.DetectorSensor',
        }

        #self._log.print(f"init done for {self.name}")
        self._log.print(f"init done")

    # @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)

    '''
    # @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()



    """
    =================================================================
        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 = super().simulator_test_results_main(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 == "get radec":
                assert cmd.is_executed()
                #assert cmd.result == "06:10:38,+89:41:02"
                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

    agent = build_agent(AgentMultiRequester, RUN_IN_THREAD=RUN_IN_THREAD)
    '''
    TEST_MODE, WITH_SIM, configfile = extract_parameters()
    #agent = AgentX()
    agent = AgentTelescopeRequester("AgentTelescopeRequester", configfile, RUN_IN_THREAD)
    agent.setSimulatorMode(TEST_MODE)
    print(agent)
    '''
    agent.run()