Commit a47c262f authored by Elisabetta Giani's avatar Elisabetta Giani
Browse files

CT-67: Added Abort command (ADR-8). Need to add handling of abort request

during configuration.
Fix error in CBF TANGO DB configuration.
parent 802d122e
Loading
Loading
Loading
Loading
Loading
+62 −66
Original line number Diff line number Diff line
@@ -214,8 +214,8 @@ class CspSubarray(SKASubarray):
            # _end_scan_event: thread event to signal EndScan
            device._end_scan_event = threading.Event()
            
            # _abort_command_event: thread event to signal Abort request
            device._abort_command_event = threading.Event()
            # _abort_obs_event: thread event to signal Abort request
            device._abort_obs_event = threading.Event()
            
            # of a long-running command
            # implemented as a default nested dictionary:
@@ -326,6 +326,10 @@ class CspSubarray(SKASubarray):
            self.logger.info("Call On Command")
            for fqdn in device._sc_subarray_fqdn:
                try:
                    # check if the sub-element subarray is already in the
                    # requested state
                    if device._sc_subarray_state[fqdn] == tango.DevState.ON:
                        continue
                    (result_code, message) = device._sc_subarray_proxies[fqdn].On()
                    if result_code == ResultCode.FAILED:
                        self.logger.error("On command failed on device {}".format(fqdn))
@@ -487,7 +491,7 @@ class CspSubarray(SKASubarray):
            target_device._command_thread['configurescan'] = threading.Thread(target=self._configure_scan,
                                                               name="Thread-Configure",
                                                               args=(thread_args,))
            target_device._abort_command_event.clear()
            target_device._abort_obs_event.clear()
            target_device._cmd_execution_state['configurescan'] = CmdExecState.RUNNING
            target_device._cmd_duration_measured['configurescan'] = 0
            target_device._command_thread['configurescan'].start()
@@ -673,7 +677,7 @@ class CspSubarray(SKASubarray):
                target_device._scan_id = int(argin)
            except (ValueError, Exception) as err:
                msg = "Scan command invalid argument:{}".format(str(err))
                self.logging.error(msg)
                self.logger.error(msg)
                return (ResultCode.FAILED, msg) 
            # invoke the constructor for the command thread
            self.logger.info("Received Scan command with id:{}".format(target_device._scan_id))
@@ -723,67 +727,49 @@ class CspSubarray(SKASubarray):
            device_done = defaultdict(lambda:False)
            elapsed_time = 0
            starting_time = time.time()
            stop_scan = False
            target_device._end_scan_event.clear()
            target_device._abort_obs_event.clear()
            # inside the end-less loop check the obsState of each sub-component
            while True:
                # Note: CbfSubarray changes the obsState value after forwarding the command
                # (synchrnously) to FSP and VCC devices. This means that When the thread function enters,
                # the loop, the obsState is still READY and the function exits immediately.
                # Adding the wait delay here let the CbfSubarray to change the obsState and 
                # generate the event.
                # Need to modify the CbfSubarray behavior
                # TODO: add check of abort_command_event.
                #if self._abort_command_event.is_set():
                #    dev_successful_state = ObsState.IDLE
                #if self._end_scan_event.is_set() or self._abort_command_event.is_set():
                self.logger.info("abort:{}".format(target_device._abort_obs_event.is_set()))
                self.logger.info("end:{}".format(target_device._end_scan_event.is_set()))
                if target_device._end_scan_event.is_set() or target_device._abort_obs_event.is_set(): 
                    if not stop_scan:
                        stop_scan = True
                        starting_time = time.time()
                        cmd_name = 'abort'
                        if target_device._end_scan_event.is_set():
                            cmd_name = 'endscan'
                    elapsed_time = time.time() - starting_time
                    self.logger.info("elapsed_time:{}".format(elapsed_time))
                    for device in device_list:
                    if device_done[device] == True:
                        continue
                    # if the sub-component execution flag is no more RUNNING, the command has
                    # ended with or without success. Go to check next device state.
                    if target_device._sc_subarray_obs_state[device] == dev_successful_state:
                        self.logger.info("Command {} ended with success on device {}.".format(cmd_name,
                                                                                            device))
                        # update the list and number of device that completed the task
                        target_device._num_dev_completed_task[cmd_name]  += 1
                        target_device._list_dev_completed_task[cmd_name].append(device)
                        # reset the value of the attribute reporting the execution state of
                        # the command
                        target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE
                        target_device._sc_subarray_cmd_progress[device][cmd_name] = 100
                        # command success: step to next device
                        device_done[device] = True
                        # check if sub-element command ended throwing an exception: in this case the
                        # 'cmd_ended_cb' callback is invoked.
                    if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.FAILED or\
                            target_device._sc_subarray_obs_state[device] == ObsState.FAULT:
                        # execution ended for this sub-element, skip to the next one
                        if target_device._sc_subarray_obs_state[device] != ObsState.SCANNING:
                            if target_device._sc_subarray_obs_state[device] == ObsState.FAULT:
                                target_device._failure_raised = True
                            device_done[device] = True
                        target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE
                    # TODO: handle connection problems
                    #if target_device._sc_subarray_state[device] == DevState.UNKNOWN:
                    #    self.logger.warning("Connection with device {} temporaly down".format(device))
                if target_device._end_scan_event.is_set():
                        self.logger.info("abort timeout value: {}".format(target_device._sc_subarray_cmd_duration_expected[device][cmd_name]))
                        if elapsed_time > target_device._sc_subarray_cmd_duration_expected[device][cmd_name]:
                                target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE
                                target_device.timeout_expired = True
                                device_done[device] = True
                    if any(device_done.values()) and all(value == True for value in device_done.values()):
                        self.logger.info("All devices have been handled!")
                        break
                self.logger.info("Going to sleep")
                time.sleep(0.1)
                           
            # end of the while loop
            target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE
            # check for timeout/failure conditions on each sub-component
            if any(target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.FAILED for device in device_list):
                target_device._failure_raised = True
                return target_device.scan_cmd_obj.failed()
                # update the progress counter at the end of the loop 
            if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list):
            target_device._cmd_progress[cmd_name] = 100
            elapsed_time = time.time() - starting_time 
            self.logger.info("Scan elapsed time:{}".format(elapsed_time))
                target_device._last_executed_command = cmd_name
            self.logger.info("abort:{}".format(target_device._abort_obs_event.is_set()))
            if target_device._end_scan_event.is_set():
                return
            if target_device._abort_obs_event.is_set():
                if target_device._failure_raised or target_device._timeout_expired:
                    return target_device.abort_cmd_obj.failed()
                self.logger.info("Aborting ends with success!")
                return target_device.abort_cmd_obj.succeeded()

    class EndScanCommand(SKASubarray.EndScanCommand):

@@ -796,7 +782,6 @@ class CspSubarray(SKASubarray):
                device_list = target_device._sc_subarray_fqdn
            try:
                sc_group = tango.Group("EndScanGroup")
                self.logger.info("Create group!!")
                for device in device_list:
                    sc_group.add(device)
            except Exception:
@@ -805,7 +790,6 @@ class CspSubarray(SKASubarray):
            self.logger.info("Issue EndScan")
            answers = sc_group.command_inout("EndScan")
            target_device._end_scan_event.set()
            self.logger.info("end scan set: {}".format(format(target_device._end_scan_event.is_set())))
            for reply in answers: 
                if reply.has_failed(): 
                    for err in reply.get_err_stack(): 
@@ -817,6 +801,7 @@ class CspSubarray(SKASubarray):
                return (ResultCode.FAILED, "EndScan Command FAILED")
            return (ResultCode.OK, "EndScan command executed OK")


    class ObsResetCommand(SKASubarray.ObsResetCommand):
        def do(self):
            self.logger.info("Call ObsReset")
@@ -827,11 +812,20 @@ class CspSubarray(SKASubarray):
                # need to add a check also on PSTBeams belonging to subarray
                device_list = target_device._sc_subarray_fqdn
            for device in device_list:
                if target_device._sc_subarray_obs_state[device] == ObsState.FAULT:
                if target_device._sc_subarray_obs_state[device] in [ObsState.FAULT, ObsState.ABORTED]:
                    devices_to_reset.append(device)
            self.logger.info("devices_to_reset:{}".format(devices_to_reset))
            if not any(devices_to_reset):
                return (ResultCode.OK, "ObsReset command OK")
                result_code = ResultCode.OK
                msg = "ObsReset command OK"
                for device in device_list:
                    if target_device._sc_subarray_obs_state[device] == ObsState.IDLE:
                        continue
                    if target_device._sc_subarray_obs_state[device] == ObsState.READY:
                        (result_code, msg) = target_device.gotoidle_cmd_obj.do()
                        self.logger.info("result_code: {}".format(result_code))
                #return (ResultCode.OK, "ObsReset command OK")
                return (result_code, msg)
            for device in devices_to_reset:
                try:
                    proxy = target_device._sc_subarray_proxies[device]
@@ -848,7 +842,6 @@ class CspSubarray(SKASubarray):
                                                               name="Thread-ObsReset",
                                                               args=(devices_to_reset,))
            target_device._command_thread['obsreset'].start()
            # set the threading endScan event 
            return (ResultCode.STARTED, "ObsReset command executed STARTED")

        def _monitor_obsreset(self, device_list):
@@ -899,30 +892,31 @@ class CspSubarray(SKASubarray):
                self.logger.info("ObsReset ends with success")
                return target_device.obsreset_cmd_obj.succeeded()

    '''
    class AbortCommand(SKASubarray.AbortCommand):

        def do(self):
            device = self.target
            device_list = device._sc_subarray_assigned_fqdn
            if not any(device._sc_subarray_assigned_fqdn):
                # beed to add a check also on PSTBeams belonging to subarray
                # need to add a check also on PSTBeams belonging to subarray
                device_list = device._sc_subarray_fqdn
            for fqdn in device_list:
                try:
                    proxy = device._sc_subarray_proxies[fqdn]
                    proxy.command_inout_asynch("Abort", self._cmd_ended_cb)
                    proxy.command_inout_asynch("Abort", device._cmd_ended_cb)
                except KeyError as key_err:
                    self.logger.warning("No key {} found".format(key_err))
                    device._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED
                except tango.DevFailed as tango_err:
                    device._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED
                    self.logger.warning(tango_err.args[0].desc)
            device._abort_command_event.set()
            message = "Abort command completed OK"
            device._abort_obs_event.set()
            self.logger.info("abort is set? {}".format(device._abort_obs_event.is_set()))
            message = "Abort command completed STARTED"
            self.logger.info(message)
            return (ResultCode.OK, message)
            return (ResultCode.STARTED, message)
    
    '''
    class GoToIdleCommand(ActionCommand):
        """
        A class for the CSPSubarray's GoToIdle() command.
@@ -1626,10 +1620,12 @@ class CspSubarray(SKASubarray):
        self.scan_cmd_obj = self.ScanCommand(*args)
        self.gotoidle_cmd_obj = self.GoToIdleCommand(*args)
        self.obsreset_cmd_obj = self.ObsResetCommand(*args)
        self.abort_cmd_obj = self.AbortCommand(*args)
        self.register_command_object("GoToIdle", self.GoToIdleCommand(*args))
        self.register_command_object("Configure", self.ConfigureCommand(*args))
        self.register_command_object("Scan", self.ScanCommand(*args))
        self.register_command_object("ObsReset", self.ObsResetCommand(*args))
        self.register_command_object("Abort", self.AbortCommand(*args))


    # ----------------
+1 −1
Original line number Diff line number Diff line
@@ -288,7 +288,7 @@
                                "mid_csp_cbf/pssconfig/02"
                            ],
                            "CorrConfigAddress": [
                                "mid_csp_cbf/corrconfig/01"
                                "mid_csp_cbf/corrconfig/02"
                            ],
                            "SubID": [
                                "2"