AgentMultiRequester.py 14.1 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
#!/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 = 150
    # Who should I send commands to ?
    #TEST_COMMANDS_DEST = "myself"
    #TEST_COMMANDS_DEST = "AgentDeviceTelescopeGemini"

    # Scenarios to be executed

    TEST_COMMANDS_LIST_GEMINI_AND_SBIG_SIMPLE = [
        'ad_mount do_flush_commands',
        'ad_filtersel do_flush_commands',

        # Not executed because not known by Mount (but by the general DC Gemini only)
        'ad_mount get_date',

        # for test purpose only
        'ad_sensor get_date',
        'ad_sensor set_date 21/10/19',
        'ad_sensor get_date',

        'ad_mount get_ra',
        #'ad_mount get_dec',
        #'ad_mount get_radec',        
        'ad_mount set_ra 14:20:51',
        'ad_mount get_dec',
        'ad_mount set_dec +86:57:48',
        'ad_mount get_ra',
        'ad_mount get_ra',
        'ad_mount get_dec',
        'ad_mount get_radec',
        'ad_mount set_radec 15:20:51 +87:57:48',
        'ad_mount get_radec',

        # Optional
        'ad_mount do_exit',
        'ad_filtersel do_exit',
    ]
    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 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',

        # Commands ok for REAL GEMINI (not the simulator, but the REAL hardware telescope)
        'ad_mount get_ra',
        'ad_mount get_dec',
        'ad_mount get_radec',
        # another alias to the same DC and same DCC (ad_mount2 is the same as ad_mount, both point to AD_Gemini.Mount)
        'ad_mount2 get_radec',
        # another alias to the same DC but not the same DCC
        'ad_mount3 get_radec',
        #'ad_mount set_ra 14:20:51'
        #'ad_mount set_dec +86:57:48'
        #'ad_mount set_radec 14:20:51 +86:57:48',
        #'ad_mount do_goto_radec 14:20:51 +86:57:48',

        # 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',

        # !!! UNSAFE FOR REAL DEVICES !!!
        'ad_mount do_init',
        'ad_filtersel do_init',
        ###'ad_shutter do_init',
        ###'ad_sensor do_init',

        # ERROR cases
        # Unknown AD alias
        'ad_unknown get_dec',
        # Unknown generic command
        'ad_mount do_unknown',
        # Unimplemented generic command
        'ad_mount do_unimplemented',
        # AD specific command implemented (OK)
        'ad_mount do_ad_gemini_specific1',
        # AD specific command UNimplemented (KO)
        'ad_mount do_ad_gemini_specific3_unimplemented',
        # AD specific command implemented (OK)
        ##'ad_mount set_ad_gemini_specific2',

        ##'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_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_GEMINI_AND_SBIG
    TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_SBIG_ONLY
    TEST_COMMANDS_LIST = TEST_COMMANDS_LIST_GEMINI_AND_SBIG_SIMPLE


    """
    =================================================================
        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':          'AgentDeviceGemini.DC_Mount',
            'ad_filtersel':     'AgentDeviceSBIG.DC_FilterSelector',
            'ad_shutter':       'AgentDeviceSBIG.DC_DetectorShutter',
            'ad_sensor':        'AgentDeviceSBIG.DC_DetectorSensor',
        }
        '''
        self._my_client_agents = {
            'ad_mount':         'AgentDeviceGemini.Mount',
            'ad_mount2':        'AgentDeviceGemini.Mount',
            'ad_mount3':        'AgentDeviceGemini.MountBis',
            '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 TEST_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()