Beispiel #1
0
    def track_thread(self):
        """This thread writes coordinates to desiredPointing on DishMaster at the rate of 20 Hz."""
        self.logger.info(
            f"print track_thread thread name:{threading.currentThread().getName()}"
            f"{threading.get_ident()}")
        device_data = self.target
        dish_client = TangoClient(self.dish_master_fqdn)
        azel_converter = AzElConverter(self.logger)

        while device_data.event_track_time.is_set() is False:
            now = datetime.datetime.utcnow()
            timestamp = str(now)
            utc_time = now.replace(tzinfo=timezone.utc)
            utc_timestamp = utc_time.timestamp()
            # pylint: disable=unbalanced-tuple-unpacking
            device_data.az, device_data.el = azel_converter.point(
                self.ra_value, self.dec_value, timestamp)

            if not self._is_elevation_within_mechanical_limits():
                time.sleep(0.05)
                continue

            if device_data.az < 0:
                device_data.az = 360 - abs(device_data.az)

            if device_data.event_track_time.is_set():
                log_message = f"Break loop: {device_data.event_track_time.is_set()}"
                self.logger.debug(log_message)
                break

            # TODO (kmadisa 11-12-2020) Add a pointing lead time to the current time (like we do on MeerKAT)
            # utc_timestamp is the time used for AzEl calculation. For the timestamp to be a future timestamp
            # on DishMaster, 100 ms are added to it.
            desired_pointing = [
                (utc_timestamp * 1000) + 100,
                round(device_data.az, 12),
                round(device_data.el, 12),
            ]
            self.logger.debug("desiredPointing coordinates: %s",
                              desired_pointing)
            dish_client.deviceproxy.desiredPointing = desired_pointing
            if (self.track_on_dish == False):
                command_name = "Track"
                dish_client = TangoClient(self.dish_master_fqdn)
                cmd_ended_cb = CommandCallBack(self.logger).cmd_ended_cb
                dish_client.send_command_async(command_name,
                                               callback_method=cmd_ended_cb)
                self.logger.info("'%s' command executed successfully.",
                                 command_name)
                self.track_on_dish = True

            time.sleep(0.05)
Beispiel #2
0
    def _subscribe_cmd_res_attribute_events(self, attributes):
        """Method to subscribe the commandResult attributes"""
        device_data = DeviceData.get_instance()
        mccs_controller_client = TangoClient(device_data.mccs_controller_fqdn)
        device_data.attr_event_map[
            "mccs_controller_client"] = mccs_controller_client

        for attribute_name in attributes:
            try:
                device_data.attr_event_map[
                    attribute_name] = mccs_controller_client.subscribe_attribute(
                        attribute_name, self.command_result_cb)
            except DevFailed as dev_failed:
                self.logger.exception(dev_failed)
                log_message = (
                    f"Exception occurred while subscribing to mccs attribute: {attribute_name}"
                )
                self.this_server.write_attr("activityMessage", log_message,
                                            False)
                tango.Except.re_throw_exception(
                    dev_failed,
                    "Exception in StartupTelescope command",
                    log_message,
                    "CentralNode.{}Command".format("StartUpTelescope"),
                    tango.ErrSeverity.ERR,
                )
    def check_allowed(self):
        """
        Checks whether this command is allowed to be run in current device state

        return:
            True if this command is allowed to be run in current device state

        rtype:
            boolean

        raises:
            DevFailed if this command is not allowed to be run in current device state

        """
        if self.state_model.op_state in [DevState.UNKNOWN, DevState.DISABLE]:
            tango.Except.throw_exception(
                f"Restart() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke Restart command on CspSubarrayLeafNode.",
                "cspsubarrayleafnode.Restart()",
                tango.ErrSeverity.ERR,
            )

        this_server = TangoServerHelper.get_instance()
        csp_subarray_fqdn = this_server.read_property("CspSubarrayFQDN")[0]
        csp_sa_client = TangoClient(csp_subarray_fqdn)
        if csp_sa_client.get_attribute("obsState").value not in [
                ObsState.FAULT, ObsState.ABORTED
        ]:
            tango.Except.throw_exception(const.ERR_UNABLE_RESTART_CMD,
                                         const.ERR_RESTART_INVOKING_CMD,
                                         "CspSubarrayLeafNode.RestartCommand",
                                         tango.ErrSeverity.ERR)
        return True
Beispiel #4
0
    def do(self):
        """
        Method to invoke Endscan command on CSP Subarray.

        return:
            None

        raises:
            DevFailed if the command execution is not successful

        """
        try:
            this_server = TangoServerHelper.get_instance()
            csp_subarray_fqdn = ""
            property_val = this_server.read_property("CspSubarrayFQDN")
            csp_subarray_fqdn = csp_subarray_fqdn.join(property_val)
            csp_sub_client_obj = TangoClient(csp_subarray_fqdn)
            csp_sub_client_obj.send_command_async(const.CMD_ENDSCAN, None,
                                                  self.endscan_cmd_ended_cb)
            this_server.write_attr("activityMessage",
                                   const.STR_ENDSCAN_SUCCESS, False)
            self.logger.info(const.STR_ENDSCAN_SUCCESS)

        except DevFailed as dev_failed:
            log_msg = f"{const.ERR_ENDSCAN_INVOKING_CMD}{dev_failed}"
            this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.STR_ENDSCAN_EXEC,
                log_msg,
                "CspSubarrayLeafNode.EndScanCommand",
                tango.ErrSeverity.ERR,
            )
    def do(self, argin):
        """
        Invokes Endscan command on DishMaster.

        param argin:
            timestamp

        raises:
            DevFailed If error occurs while invoking StopCapture command on DishMaster.

        """
        command_name = "EndScan"
        cmd_ended_cb = CommandCallBack(self.logger).cmd_ended_cb

        try:
            this_server = TangoServerHelper.get_instance()
            self.dish_master_fqdn = ""
            property_value = this_server.read_property("DishMasterFQDN")
            self.dish_master_fqdn = self.dish_master_fqdn.join(property_value)
            dish_client = TangoClient(self.dish_master_fqdn)
            dish_client.send_command_async("StopCapture", callback_method=cmd_ended_cb)
            self.logger.info("'%s' command executed successfully.", command_name)
        except DevFailed as dev_failed:
            self.logger.exception(dev_failed)
            log_message = (
                f"Exception occured while executing the '{command_name}' command."
            )
            this_server.write_attr("activityMessage", log_message, False)
            tango.Except.re_throw_exception(
                dev_failed,
                f"Exception in '{command_name}' command.",
                log_message,
                "EndScan.do()",
                tango.ErrSeverity.ERR,
            )
Beispiel #6
0
    def check_allowed(self):
        """
        Checks whether this command is allowed to be run in current device state

        :return: True if this command is allowed to be run in current device state

        :rtype: boolean

        :raises: DevFailed if this command is not allowed to be run in current device state

        """
        if self.state_model.op_state in [DevState.UNKNOWN, DevState.DISABLE]:
            log_msg = f"ObsReset() is not allowed in {self.state_model.op_state}"
            tango.Except.throw_exception(
                log_msg,
                "Failed to invoke ObsReset command on MccsSubarrayLeafNode.",
                "mccssubarrayleafnode.ObsReset()",
                tango.ErrSeverity.ERR,
            )
        self.this_server = TangoServerHelper.get_instance()
        self.mccs_sa_fqdn = self.this_server.read_property(
            "MccsSubarrayFQDN")[0]
        self.mccs_sa_client = TangoClient(self.mccs_sa_fqdn)
        if self.mccs_sa_client.get_attribute("obsState").value not in [
                ObsState.ABORTED, ObsState.FAULT
        ]:
            tango.Except.throw_exception(
                const.ERR_DEVICE_NOT_IN_VALID_OBSTATE,
                const.ERR_OBSRESET_INVOKING_CMD,
                "MccsSubarrayLeafNode.ObsResetCommand", tango.ErrSeverity.ERR)

        return True
    def check_allowed(self):
        """
        Checks whether this command is allowed to be run in current device state.

        :return: True if this command is allowed to be run in current device state.

        :rtype: boolean

        :raises: Exception if command execution throws any type of exception.

        """
        self.this_server = TangoServerHelper.get_instance()
        sdp_subarray_fqdn = self.this_server.read_property(
            "SdpSubarrayFQDN")[0]
        self.sdp_sa_ln_client_obj = TangoClient(sdp_subarray_fqdn)

        if self.state_model.op_state in [
                DevState.FAULT,
                DevState.UNKNOWN,
                DevState.DISABLE,
        ]:
            tango.Except.throw_exception(
                f"Scan() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke Scan command on SdpSubarrayLeafNode.",
                "sdpsubarrayleafnode.Scan()",
                tango.ErrSeverity.ERR,
            )

        if self.sdp_sa_ln_client_obj.get_attribute(
                "obsState").value != ObsState.READY:
            tango.Except.throw_exception(
                const.ERR_DEVICE_NOT_READY, const.STR_SCAN_EXEC,
                "SdpSubarrayLeafNode.StartScanCommand", tango.ErrSeverity.ERR)
        return True
Beispiel #8
0
    def do(self):
        """
        This command invokes Abort command on CSP Subarray.

        return:
            None

        raises:
            DevFailed if error occurs while invoking command on CSP Subarray.

        """
        try:
            this_server = TangoServerHelper.get_instance()
            csp_subarray_fqdn = ""
            property_val = this_server.read_property("CspSubarrayFQDN")
            csp_subarray_fqdn = csp_subarray_fqdn.join(property_val)
            csp_sub_client_obj = TangoClient(csp_subarray_fqdn)
            csp_sub_client_obj.send_command_async(const.CMD_ABORT, None,
                                                  self.abort_cmd_ended_cb)
            this_server.write_attr("activityMessage", const.STR_ABORT_SUCCESS,
                                   False)
            self.logger.info(const.STR_ABORT_SUCCESS)

        except DevFailed as dev_failed:
            log_msg = f"{const.ERR_ABORT_INVOKING_CMD}{dev_failed}"
            this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.STR_ABORT_EXEC,
                log_msg,
                "CspSubarrayLeafNode.AbortCommand",
                tango.ErrSeverity.ERR,
            )
Beispiel #9
0
    def subarray_health_subscribe_event(self):
        """
        Method to subscribe to health state change event on SubarrayNode.

        :raises: Devfailed exception if erroe occures while subscribing event.
        """
        for subarray_fqdn in self.this_server.read_property(
                "TMLowSubarrayNodes"):
            subarray_client = TangoClient(subarray_fqdn)
            # updating the subarray_health_state_map with device name (as ska_mid/tm_subarray_node/1) and its value which is required in callback
            try:
                event_id = subarray_client.subscribe_attribute(
                    const.EVT_SUBSR_HEALTH_STATE, self.health_state_cb)
                self.health_state_event_map[subarray_client] = event_id

            except DevFailed as dev_failed:
                log_msg = f"{const.ERR_SUBSR_SA_HEALTH_STATE}{dev_failed}"
                self.logger.exception(dev_failed)
                self.this_server.write_attr("activityMessage",
                                            const.ERR_SUBSR_SA_HEALTH_STATE,
                                            False)
                tango.Except.throw_exception(
                    const.STR_CMD_FAILED,
                    log_msg,
                    "CentralNode.HealthStateSubscribeEvent",
                    tango.ErrSeverity.ERR,
                )
Beispiel #10
0
    def do(self):
        """
        Method to invoke Standby command on SDP Master.

        :param argin: None.

        return:
            None
        """
        this_server = TangoServerHelper.get_instance()
        try:
            sdp_master_ln_fqdn = ""
            property_val = this_server.read_property("SdpMasterFQDN")[0]
            sdp_master_ln_fqdn = sdp_master_ln_fqdn.join(property_val)
            sdp_mln_client_obj = TangoClient(sdp_master_ln_fqdn)
            sdp_mln_client_obj.send_command_async(
                const.CMD_STANDBY, callback_method=self.standby_cmd_ended_cb
                )
            log_msg = const.CMD_STANDBY + const.STR_COMMAND + const.STR_INVOKE_SUCCESS
            self.logger.debug(log_msg)

        except DevFailed as dev_failed:
            self.logger.exception(dev_failed)
            log_msg = f"{const.ERR_STANDBY_CMD_FAIL}{dev_failed}"
            tango.Except.re_throw_exception(
                dev_failed,
                const.ERR_INVOKING_CMD,
                log_msg,
                "SdpMasterLeafNode.StandbyCommand()",
                tango.ErrSeverity.ERR,
            )
Beispiel #11
0
    def check_allowed(self):
        """
        Checks whether this command is allowed to be run in current device state

        :return: True if this command is allowed to be run in current device state

        :rtype: boolean

        :raises: DevFailed if this command is not allowed to be run in current device state

        """
        self.this_server = TangoServerHelper.get_instance()
        sdp_subarray_fqdn = self.this_server.read_property(
            "SdpSubarrayFQDN")[0]
        self.sdp_sa_ln_client_obj = TangoClient(sdp_subarray_fqdn)

        if self.state_model.op_state in [DevState.UNKNOWN, DevState.DISABLE]:
            tango.Except.throw_exception(
                f"Restart() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke Restart command on SdpSubarrayLeafNode.",
                "sdpsubarrayleafnode.Restart()",
                tango.ErrSeverity.ERR,
            )

        if self.sdp_sa_ln_client_obj.get_attribute("obsState").value not in [
                ObsState.ABORTED, ObsState.FAULT
        ]:
            tango.Except.throw_exception(const.ERR_DEVICE_NOT_ABORTED_FAULT,
                                         const.ERR_RESTART_INVOKING_CMD,
                                         "SdpSubarrayLeafNode.Restart()",
                                         tango.ErrSeverity.ERR)
        return True
    def check_allowed(self):
        """
        Checks whether the command is allowed to be run in the current state

        :return: True if this command is allowed to be run in current device state

        :rtype: boolean

        :raises: DevFailed if this command is not allowed to be run in current device state

        """
        if self.state_model.op_state in [
                DevState.FAULT,
                DevState.UNKNOWN,
                DevState.DISABLE,
        ]:
            tango.Except.throw_exception(
                f"ReleaseAllResources() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke ReleaseAllResources command on "
                "cspsubarrayleafnode.",
                "cspsubarrayleafnode.ReleaseAllResources()",
                tango.ErrSeverity.ERR,
            )

        this_server = TangoServerHelper.get_instance()
        csp_subarray_fqdn = this_server.read_property("CspSubarrayFQDN")[0]
        csp_sa_client = TangoClient(csp_subarray_fqdn)
        if csp_sa_client.get_attribute("obsState").value != ObsState.IDLE:
            tango.Except.throw_exception(
                const.ERR_DEVICE_NOT_IDLE,
                "Failed to invoke ReleaseAllResourcesCommand command on cspsubarrayleafnode.",
                "CspSubarrayLeafNode.ReleaseAllResourcesCommand",
                tango.ErrSeverity.ERR)

        return True
Beispiel #13
0
    def check_allowed(self):
        """
        Checks whether this command is allowed to be run in current device state

        :return: True if this command is allowed to be run in current device state

        :rtype: boolean

        :raises: Exception if command execution throws any type of exception

        """
        self.this_server = TangoServerHelper.get_instance()
        sdp_subarray_fqdn = self.this_server.read_property("SdpSubarrayFQDN")[0]
        self.sdp_sa_ln_client_obj = TangoClient(sdp_subarray_fqdn)

        if self.state_model.op_state in [
            DevState.FAULT,
            DevState.UNKNOWN,
            DevState.DISABLE,
        ]:
            tango.Except.throw_exception(
                f"ReleaseAllResources() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke ReleaseAllResources command on "
                "SdpSubarrayLeafNode.",
                "SdpSubarrayLeafNode.ReleaseAllResources()",
                tango.ErrSeverity.ERR,
            )

        if self.sdp_sa_ln_client_obj.get_attribute("obsState").value != ObsState.IDLE:
            tango.Except.throw_exception(const.STR_RELEASE_RES_EXEC, const.ERR_RELEASE_RESOURCES,
                                            "SdpSubarrayLeafNode.ReleaseAllResources()",
                                            tango.ErrSeverity.ERR)
        return True
def test_activity_message_attribute_reports_correct_csp_health_state_callbacks(
    mock_csp_master_proxy, health_state, mock_tango_server_helper
):
    (
        device_proxy,
        tango_client_obj,
        csp_master_fqdn,
        event_subscription_map,
    ) = mock_csp_master_proxy
    with mock.patch.object(
        TangoClient, "_get_deviceproxy", return_value=Mock()
    ) as mock_obj:
        with mock.patch.object(
            TangoClient, "subscribe_attribute", side_effect=dummy_subscriber
        ):
            tango_client_obj = TangoClient("mid_csp/elt/master")
            device_proxy.On()
    device_data = DeviceData.get_instance()
    assert (
        device_data._csp_cbf_health_state_log
        == f"CSP CBF health is {health_state.name}"
    )
    assert (
        device_data._csp_pst_health_state_log
        == f"CSP PST health is {health_state.name}."
    )
    assert (
        device_data._csp_pss_health_state_log
        == f"CSP PSS health is {health_state.name}."
    )
def event_subscription():
    event_subscription_map = {}
    with mock.patch.object(TangoClient, "_get_deviceproxy", return_value=Mock()):
        tango_client_object = TangoClient("low-mccs/subarray/01")
        tango_client_object.deviceproxy.command_inout_asynch.side_effect = lambda command_name, argument, callback, *args, **kwargs: event_subscription_map.update(
            {command_name: callback}
        )
        yield event_subscription_map
    def create_mccs_client(self, mccs_master_fqdn):
        """
        Create TangoClient for MccsMasterLeafNode node and call
        standby method.

        :return: None
        """
        mccs_mln_client = TangoClient(mccs_master_fqdn)
        self.invoke_stnadby(mccs_mln_client)
 def restart_leaf_nodes(self, leaf_node_fqdn, info_string):
     """
     set up mccs devices
     """
     # Invoke Restart command on MCCS Subarray Leaf Node.
     mccs_subarray_client = TangoClient(leaf_node_fqdn)
     mccs_subarray_client.send_command(const.CMD_RESTART)
     self.logger.info(info_string)
     self.logger.info(const.STR_RESTART_SUCCESS)
def mock_obstate_check():
    with mock.patch.object(TangoClient,
                           "_get_deviceproxy",
                           return_value=Mock()) as mock_obj:
        tango_client_obj = TangoClient("mid_sdp/elt/subarray_01")
        with mock.patch.object(
                TangoClient, "get_attribute",
                Mock(return_value=ObsState.EMPTY)) as mock_obj_obstate:
            yield tango_client_obj
Beispiel #19
0
def mock_obstate_check():
    dut_properties = {"CspSubarrayFQDN": "mid_csp/elt/subarray_01"}
    with mock.patch.object(TangoClient,
                           "_get_deviceproxy",
                           return_value=Mock()) as mock_obj:
        tango_client_obj = TangoClient(dut_properties["CspSubarrayFQDN"])
        with mock.patch.object(
                TangoClient, "get_attribute",
                Mock(return_value=ObsState.EMPTY)) as mock_obj_obstate:
            yield tango_client_obj
    def create_subarray_client(self, subarray_fqdn_list):
        """
        Create TangoClient for Subarray node and call
        standby method.

        :return: None
        """
        for subarray_fqdn in subarray_fqdn_list:
            subarray_client = TangoClient(subarray_fqdn)
            self.invoke_stnadby(subarray_client)
def event_subscription_mock():
    dut_properties = {"SdpSubarrayFQDN": "mid_sdp/elt/subarray_01"}
    event_subscription_map = {}
    with mock.patch.object(TangoClient,
                           "_get_deviceproxy",
                           return_value=Mock()) as mock_obj:
        tango_client_obj = TangoClient(dut_properties["SdpSubarrayFQDN"])
        tango_client_obj.deviceproxy.command_inout_asynch.side_effect = lambda command_name, arg, callback, *args, **kwargs: event_subscription_map.update(
            {command_name: callback})
        yield event_subscription_map
def event_subscription_mock():
    dut_properties = {"MccsMasterFQDN": "low-mccs/control/control"}
    event_subscription_map = {}
    with mock.patch.object(TangoClient,
                           "_get_deviceproxy",
                           return_value=Mock()) as mock_obj:
        tango_client_obj = TangoClient(dut_properties["MccsMasterFQDN"])
        tango_client_obj.deviceproxy.command_inout_asynch.side_effect = lambda command_name, arg, callback, *args, **kwargs: event_subscription_map.update(
            {command_name: callback})
        yield event_subscription_map
Beispiel #23
0
    def __init__(self, logger=None):
        if logger == None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger

        self.device_data = DeviceData.get_instance()
        self.this_server = TangoServerHelper.get_instance()
        self.event_id = None
        self.csp_master = TangoClient(
            self.this_server.read_property("CspMasterFQDN")[0])
Beispiel #24
0
def event_subscription_attr_mock():
    dut_properties = {"DishMasterFQDN": "mid_d0001/elt/master"}
    event_subscription_map = {}
    with mock.patch.object(
        TangoClient, "_get_deviceproxy", return_value=Mock()
    ) as mock_obj:
        tango_client_obj = TangoClient(dut_properties["DishMasterFQDN"])
        tango_client_obj.deviceproxy.subscribe_event.side_effect = lambda attr_name, event_type, callback, *args, **kwargs: event_subscription_map.update(
            {attr_name: callback}
        )
        yield event_subscription_map
Beispiel #25
0
 def subscribe(self):
     mccs_subarray_ln_fqdn = ""
     property_val = self.this_server.read_property("MccsSubarrayLNFQDN")
     mccs_subarray_ln_fqdn = mccs_subarray_ln_fqdn.join(property_val)
     self.mccs_client = TangoClient(mccs_subarray_ln_fqdn)
     # Subscribe mccsSubarrayObsState (forwarded attribute) of mccsSubarray
     mccs_event_id = self.mccs_client.subscribe_attribute(
         const.EVT_MCCSSA_OBS_STATE, self.observation_state_cb)
     self.mccs_obs_state_event_id[self.mccs_client] = mccs_event_id
     log_msg = f"{const.STR_SUB_ATTR_MCCS_SALN_OBSTATE_SUCCESS}{self.mccs_obs_state_event_id}"
     self.logger.info(log_msg)
Beispiel #26
0
    def _configure_band(self, band):
        """"Send the ConfigureBand<band-number> command to Dish Master"""
        command_name = f"ConfigureBand{band}"

        try:
            dish_client = TangoClient(self.dish_master_fqdn)
            cmd_ended_cb = CommandCallBack(self.logger).cmd_ended_cb
            dish_client.send_command_async(command_name,
                                           callback_method=cmd_ended_cb)
        except DevFailed as dev_failed:
            raise dev_failed
Beispiel #27
0
def error_in_health_state():
    device = "ska_mid/tm_leaf_node/mccs_subarray01"
    with mock.patch.object(TangoClient,
                           "_get_deviceproxy",
                           return_value=Mock()) as mock_obj:
        with mock.patch.object(
                TangoClient,
                "subscribe_attribute",
                side_effect=create_dummy_event_healthstate_with_error,
        ) as obj:
            error_health_state = TangoClient(device)
            yield error_health_state, device
Beispiel #28
0
    def __init__(self, logger=None):
        if logger == None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger

        self.mccs_ln_asigned_res_event_id = {}
        self.this_server = TangoServerHelper.get_instance()
        self.device_data = DeviceData.get_instance()
        mccs_subarray_ln_fqdn = self.this_server.read_property(
            "MccsSubarrayLNFQDN")[0]
        self.mccs_client = TangoClient(mccs_subarray_ln_fqdn)
Beispiel #29
0
    def abort_mccs(self, mccs_sa_ln_fqdn):
        """
        Create client of MCCS subarray leaf node and invoke abort command on client.

        :param argin: MCCS SubarrayLeafNode FQDN

        return:
            None
        """
        mccs_client = TangoClient(mccs_sa_ln_fqdn)
        mccs_client.send_command(const.CMD_ABORT)
        self.logger.info(const.STR_CMD_ABORT_INV_MCCS)
Beispiel #30
0
 def validate_obs_state(self):
     self.this_server = TangoServerHelper.get_instance()
     sdp_subarray_fqdn = self.this_server.read_property("SdpSubarrayFQDN")[0]
     sdp_sa_client = TangoClient(sdp_subarray_fqdn)
     if sdp_sa_client.get_attribute("obsState").value in [ObsState.EMPTY, ObsState.IDLE]:
         self.logger.info(
             "SDP subarray is in required obstate,Hence resources to SDP can be assign."
         )
     else:
         self.logger.error("Subarray is not in EMPTY obstate")
         log_msg = "Error in device obstate."
         self.this_server.write_attr("activityMessage", log_msg, False)
         raise InvalidObsStateError("SDP subarray is not in EMPTY obstate.")