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

        """
        # device = self.target
        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 CspSubarrayLeafNode.",
                "cspsubarrayleafnode.ObsReset()",
                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.ABORTED, ObsState.FAULT
        ]:
            tango.Except.throw_exception(
                const.ERR_UNABLE_OBSRESET_CMD, const.ERR_OBSRESET_INVOKING_CMD,
                "CspSubarrayLeafNode.ObsResetCommand", 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
Exemplo n.º 3
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.")
Exemplo n.º 4
0
    def do(self, argin):
        """
        Method to invoke Scan command on MCCS Subarray.

        :param argin: JSON string consists of scan id (int) and start_time.

        Example:
        {"interface":"https://schema.skatelescope.org/ska-low-mccs-scan/1.0","scan_id":1,"start_time":0.0}


        Note: Enter the json string without spaces as a input.

        return:
            None

        raises:
            DevFailed if the command execution is not successful
        """
        this_server = TangoServerHelper.get_instance()
        device_data = DeviceData.get_instance()
        try:
            mccs_subarray_fqdn = ""
            property_value = this_server.read_property("MccsSubarrayFQDN")[0]
            mccs_subarray_fqdn = mccs_subarray_fqdn.join(property_value)
            mccs_subarray_client = TangoClient(mccs_subarray_fqdn)
            assert mccs_subarray_client.get_attribute(
                "obsState").value == ObsState.READY
            mccs_subarray_client.send_command_async(const.CMD_SCAN, argin,
                                                    self.scan_cmd_ended_cb)
            this_server.write_attr("activityMessage", const.STR_SCAN_SUCCESS,
                                   False)
            self.logger.info(const.STR_SCAN_SUCCESS)

        except AssertionError as assertion_error:
            log_msg = f"{const.ERR_DEVICE_NOT_READY}{assertion_error}"
            device_data._read_activity_message = log_msg
            self.logger.exception(log_msg)
            tango.Except.throw_exception(const.STR_SCAN_EXEC, log_msg,
                                         "MccsSubarrayLeafNode.Scan",
                                         tango.ErrSeverity.ERR)

        except DevFailed as dev_failed:
            log_msg = f"{const.ERR_SCAN_RESOURCES}{dev_failed}"
            this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.STR_SCAN_EXEC,
                log_msg,
                "MccsSubarrayLeafNode.Scan",
                tango.ErrSeverity.ERR,
            )
 def validate_obs_state(self):
     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 in [
             ObsState.EMPTY,
             ObsState.IDLE,
     ]:
         self.logger.info(
             "CSP Subarray is in required obsState, resources will be assigned"
         )
     else:
         self.logger.error("CSP Subarray is not in EMPTY/IDLE obsState")
         this_server.write_attr("activityMessage",
                                "Error in device obsState", False)
         raise InvalidObsStateError(
             "CSP Subarray is not in EMPTY/IDLE obsState")
Exemplo n.º 6
0
    def do(self):
        """
        Method to invoke End command on MCCS Subarray.

        return:
            None

        raises:
            DevFailed if the command execution is not successful.
        """
        this_server = TangoServerHelper.get_instance()
        device_data = DeviceData.get_instance()
        try:
            mccs_subarray_fqdn = ""
            property_value = this_server.read_property("MccsSubarrayFQDN")[0]
            mccs_subarray_fqdn = mccs_subarray_fqdn.join(property_value)
            mccs_subarray_client = TangoClient(mccs_subarray_fqdn)
            assert mccs_subarray_client.get_attribute(
                "obsState").value == ObsState.READY
            mccs_subarray_client.send_command_async(const.CMD_END, None,
                                                    self.end_cmd_ended_cb)
            this_server.write_attr("activityMessage", const.STR_END_SUCCESS,
                                   False)
            self.logger.info(const.STR_END_SUCCESS)

        except AssertionError:
            log_msg = const.STR_OBS_STATE
            device_data._read_activity_message = const.ERR_DEVICE_NOT_READY
            self.logger.error(log_msg)
            tango.Except.throw_exception(const.STR_END_EXEC,
                                         const.ERR_DEVICE_NOT_READY,
                                         "MCCSSubarrayLeafNode.End",
                                         tango.ErrSeverity.ERR)

        except DevFailed as dev_failed:
            log_msg = f"{const.ERR_END_INVOKING_CMD}{dev_failed}"
            this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.ERR_END_INVOKING_CMD,
                log_msg,
                "MccsSubarrayLeafNode.End()",
                tango.ErrSeverity.ERR,
            )
Exemplo n.º 7
0
    def do(self):
        """
        Invokes TrackStop command on the DishMaster.

        param argin:
            None

        return:
            None

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

        """
        device_data = self.target
        command_name = "Abort"
        device_data.event_track_time.set()
        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_pointing_state = dish_client.get_attribute("pointingState")
            if (dish_pointing_state.value is not PointingState.READY):
                dish_client.send_command_async("TrackStop",
                                               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,
                "Abort.do()",
                tango.ErrSeverity.ERR,
            )
Exemplo n.º 8
0
    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

        """
        # device_data = self.target
        if self.state_model.op_state in [
                DevState.FAULT,
                DevState.UNKNOWN,
                DevState.DISABLE,
        ]:
            tango.Except.throw_exception(
                f"Configure() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke Configure command on cspsubarrayleafnode.",
                "cspsubarrayleafnode.Configure()",
                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.IDLE, ObsState.READY
        ]:
            tango.Except.throw_exception(
                const.ERR_DEVICE_NOT_READY_OR_IDLE,
                const.ERR_CONFIGURE_INVOKING_CMD,
                "CspSubarrayLeafNode.ConfigureCommand", tango.ErrSeverity.ERR)
        return True
class EndScan(BaseCommand):
    """
    A class for SdpSubarrayLeafNode's EndScan() command.

    It invokes EndScan command on Sdp Subarray.
    This command is allowed when Sdp Subarray is in SCANNING state.
    """
    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"EndScan() is not allowed in current state{self.state_model.op_state}",
                "Failed to invoke EndScan command on SdpSubarrayLeafNode.",
                "sdpsubarrayleafnode.EndScan()",
                tango.ErrSeverity.ERR,
            )

        if self.sdp_sa_ln_client_obj.get_attribute(
                "obsState").value != ObsState.SCANNING:
            tango.Except.throw_exception(const.ERR_ENDSCAN_INVOKING_CMD,
                                         const.ERR_DEVICE_NOT_IN_SCAN,
                                         "SdpSubarrayLeafNode.EndScan",
                                         tango.ErrSeverity.ERR)
        return True

    def endscan_cmd_ended_cb(self, event):
        """
        Callback function immediately executed when the asynchronous invoked command returns.
        Checks whether the endscan command has been successfully invoked on SDP Subarray.

        :param event: A CmdDoneEvent object.
        This class is used to pass data to the callback method in asynchronous callback model
        for command execution.

        :type: CmdDoneEvent object

            It has the following members:
                - device     : (DeviceProxy) The DeviceProxy object on which the call was executed.
                - cmd_name   : (str) The command name
                - argout_raw : (DeviceData) The command argout
                - argout     : The command argout
                - err        : (bool) A boolean flag set to true if the command failed. False otherwise
                - errors     : (sequence<DevError>) The error stack
                - ext

        :return: none
        """
        if event.err:
            log = f"{const.ERR_INVOKING_CMD}{event.cmd_name}\n{event.errors}"
            self.this_server.write_attr("activityMessage", log, False)
            self.logger.error(log)
        else:
            log = const.STR_COMMAND + event.cmd_name + const.STR_INVOKE_SUCCESS
            self.this_server.write_attr("activityMessage", log, False)
            self.logger.info(log)

    def do(self):
        """
        Method to invoke EndScan command on SDP Subarray.

        :param argin: None

        return:
            None

        raises:
            DevFailed if the command execution is not successful.
        """
        try:
            self.sdp_sa_ln_client_obj.send_command_async(
                const.CMD_ENDSCAN, None, self.endscan_cmd_ended_cb)
            self.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}"
            self.this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.STR_ENDSCAN_EXEC,
                log_msg,
                "SdpSubarrayLeafNode.EndScan()",
                tango.ErrSeverity.ERR,
            )
Exemplo n.º 10
0
class Restart(BaseCommand):
    """
    A class for MccsSubarrayLeafNode's Restart() command.

    Restart command is inherited from BaseCommand. This command Invokes Restart command on MCCS Controller.
    """
    def check_allowed(self):
        """
        Checks whether the command is allowed to be executed 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"Restart() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke Restart command on MccsSubarrayLeafNode.",
                "Mccssubarrayleafnode.Restart()",
                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_INVOKING_CMD, const.ERR_RESTART_COMMAND,
                "MccsSubarrayLeafNode.RestartCommand", tango.ErrSeverity.ERR)

        return True

    def restart_cmd_ended_cb(self, event):
        """
        Callback function immediately executed when the asynchronous invoked
        command returns.

        :param event: a CmdDoneEvent object. This class is used to pass data
            to the callback method in asynchronous callback model for command
            execution.

        :type: CmdDoneEvent object
            It has the following members:
                - device     : (DeviceProxy) The DeviceProxy object on which the call was executed.
                - cmd_name   : (str) The command name
                - argout_raw : (DeviceData) The command argout
                - argout     : The command argout
                - err        : (bool) A boolean flag set to true if the command failed. False otherwise
                - errors     : (sequence<DevError>) The error stack
                - ext

        :return: none
        """
        # Update logs and activity message attribute with received event
        if event.err:
            log_msg = f"{const.ERR_INVOKING_CMD}{event.cmd_name}\n{event.errors}"
            self.logger.error(log_msg)
            self.this_server.write_attr("activityMessage", log_msg, False)
        else:
            log_msg = f"{const.STR_COMMAND}{event.cmd_name}{const.STR_INVOKE_SUCCESS}"
            self.logger.info(log_msg)
            self.this_server.write_attr("activityMessage", log_msg, False)

    def do(self):
        """
         Method to invoke Restart command on MCCS Controller.

        :param argin: None

        return:
            None

        raises:
            DevFailed if the command execution is not successful

        """
        try:
            # On mccs side this implementation is not finalize yet modifications are expected.
            # Hence hardcoded controller FQDN and input arguement (subarray ID).
            mccs_controller_fqdn = "low-mccs/control/control"
            input_to_mccs_controller = {"subarray_id": 1}
            argin = json.dumps(input_to_mccs_controller)
            mccs_controller_client = TangoClient(mccs_controller_fqdn)
            mccs_controller_client.send_command_async(
                const.CMD_RESTART, argin, self.restart_cmd_ended_cb)
            self.this_server.write_attr("activityMessage",
                                        const.STR_RESTART_SUCCESS, False)
            self.logger.info(const.STR_RESTART_SUCCESS)

        except DevFailed as dev_failed:
            log_msg = f"{const.ERR_RESTART_COMMAND}{dev_failed}"
            self.this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.ERR_RESTART_COMMAND,
                log_msg,
                "MccsSubarrayLeafNode.Restart",
                tango.ErrSeverity.ERR,
            )
Exemplo n.º 11
0
class Abort(BaseCommand):
    """
    A class for MccsSubarrayLeafNode's Abort() command.

    Command to abort the current operation being done on the MCCS Subarray.

    """
    def check_allowed(self):
        """
        Checks whether the command is allowed to be executed 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"Abort() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke Abort command on MccsSubarrayLeafNode.",
                "Mccssubarrayleafnode.Abort()",
                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.READY, ObsState.CONFIGURING, ObsState.SCANNING,
                ObsState.IDLE, ObsState.RESETTING
        ]:
            tango.Except.throw_exception(const.ERR_DEVICE_NOT_IN_VALID_OBSTATE,
                                         const.ERR_ABORT_COMMAND,
                                         "MccsSubarrayLeafNode.Abort()",
                                         tango.ErrSeverity.ERR)
        return True

    def abort_cmd_ended_cb(self, event):
        """
        Callback function immediately executed when the asynchronous invoked
        command returns.

        :param event: a CmdDoneEvent object. This class is used to pass data
            to the callback method in asynchronous callback model for command
            execution.

        :type: CmdDoneEvent object
            It has the following members:
                - device     : (DeviceProxy) The DeviceProxy object on which the call was executed.
                - cmd_name   : (str) The command name
                - argout_raw : (DeviceData) The command argout
                - argout     : The command argout
                - err        : (bool) A boolean flag set to true if the command failed. False otherwise
                - errors     : (sequence<DevError>) The error stack
                - ext

        :return: none
        """
        # Update logs and activity message attribute with received event
        if event.err:
            log_msg = f"{const.ERR_INVOKING_CMD}{event.cmd_name}\n{event.errors}"
            self.logger.error(log_msg)
            self.this_server.write_attr("activityMessage", log_msg, False)
        else:
            log_msg = f"{const.STR_COMMAND}{event.cmd_name}{const.STR_INVOKE_SUCCESS}"
            self.logger.info(log_msg)
            self.this_server.write_attr("activityMessage", log_msg, False)

    def do(self):
        """
         Method to invoke Abort command on MCCS Subarray.

        :param argin: None

        return:
            None

        raises:
            DevFailed if the command execution is not successful

        """
        try:
            self.mccs_sa_client.send_command_async(const.CMD_ABORT, None,
                                                   self.abort_cmd_ended_cb)
            self.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_COMMAND}{dev_failed}"
            self.this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.ERR_ABORT_COMMAND,
                log_msg,
                "MccsSubarrayLeafNode.Abort",
                tango.ErrSeverity.ERR,
            )
Exemplo n.º 12
0
class Configure(BaseCommand):
    """
    A class for SdpSubarrayLeafNode's Configure() command.

    Configures the SDP Subarray device by providing the SDP PB
    configuration needed to execute the receive workflow

    """

    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"Configure() is not allowed in current state {self.state_model.op_state}",
                "Failed to invoke Configure command on SdpSubarrayLeafNode.",
                "sdpsubarrayleafnode.Configure()",
                tango.ErrSeverity.ERR,
            )

        if self.sdp_sa_ln_client_obj.get_attribute("obsState").value not in [ObsState.IDLE, ObsState.READY]:
            tango.Except.throw_exception(const.ERR_DEVICE_NOT_READY_OR_IDLE, const.ERR_CONFIGURE,
                                         "SdpSubarrayLeafNode.ConfigureCommand",
                                         tango.ErrSeverity.ERR)
        return True

    def configure_cmd_ended_cb(self, event):
        """
        Callback function immediately executed when the asynchronous invoked command returns.
        Checks whether the configure command has been successfully invoked on SDP Subarray.

        :param event: A CmdDoneEvent object. This class is used to pass data to the callback method in asynchronous
                        callback model for command execution.

        :type: CmdDoneEvent object

            It has the following members:
                - device     : (DeviceProxy) The DeviceProxy object on which the call was executed.
                - cmd_name   : (str) The command name
                - argout_raw : (DeviceData) The command argout
                - argout     : The command argout
                - err        : (bool) A boolean flag set to true if the command failed. False otherwise
                - errors     : (sequence<DevError>) The error stack
                - ext

        :return: none
        """
        if event.err:
            log = f"{const.ERR_INVOKING_CMD}{event.cmd_name}\n{event.errors}"
            self.this_server.write_attr("activityMessage", log, False)
            self.logger.error(log)
        else:
            log = const.STR_COMMAND + event.cmd_name + const.STR_INVOKE_SUCCESS
            self.this_server.write_attr("activityMessage", log, False)
            self.logger.info(log)

    @identify_with_id("configure", "argin")
    def do(self, argin):
        """
        Method to invoke Configure command on SDP Subarray.

        :param argin: The string in JSON format. The JSON contains following values:

        Example:

        { "scan_type": "science_A" }

        return:
            None

        raises:
            ValueError if input argument json string contains invalid value.

            KeyError if input argument json string contains invalid key.

            DevFailed if the command execution is not successful
        """
        try:
            log_msg = (
                "Input JSON for SDP Subarray Leaf Node Configure command is: " + argin
            )
            self.logger.debug(log_msg)
            self.sdp_sa_ln_client_obj.send_command_async(
                const.CMD_CONFIGURE, command_data=argin, callback_method=self.configure_cmd_ended_cb
                )
            self.this_server.write_attr("activityMessage", const.STR_CONFIGURE_SUCCESS, False)
            self.logger.info(const.STR_CONFIGURE_SUCCESS)

        except DevFailed as dev_failed:
            log_msg = f"{const.ERR_CONFIGURE}{dev_failed}"
            self.this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.STR_CONFIG_EXEC,
                log_msg,
                "SdpSubarrayLeafNode.Configure()",
                tango.ErrSeverity.ERR,
            )
    def do(self, argin):
        """
        Method to invoke Configure command on MCCS Subarray.

        :param argin: DevString.
                      The string in JSON format. The JSON contains following values:

        Example:
        {'interface':'https://schema.skatelescope.org/ska-low-tmc-configure/1.0','stations':[{'station_id':1},{'station_id':2}],'subarray_beams':[{'subarray_beam_id':1,'station_ids':[1,2],'update_rate':0.0,'channels':[[0,8,1,1],[8,8,2,1],[24,16,2,1]],'antenna_weights':[1.0,1.0,1.0],'phase_centre':[0.0,0.0],'target':{'system':'HORIZON','name':'DriftScan','az':180.0,'el':45.0}}]}

        Note: Enter the json string without spaces as a input.

        return:
            None

        raises:
            DevFailed if the command execution is not successful

            ValueError if input argument json string contains invalid value

            KeyError if input argument json string contains invalid key
        """
        this_server = TangoServerHelper.get_instance()
        device_data = DeviceData.get_instance()
        try:
            mccs_subarray_fqdn = ""
            property_value = this_server.read_property("MccsSubarrayFQDN")[0]
            mccs_subarray_fqdn = mccs_subarray_fqdn.join(property_value)
            mccs_subarray_client = TangoClient(mccs_subarray_fqdn)
            assert (mccs_subarray_client.get_attribute("obsState").value
                    in (ObsState.IDLE, ObsState.READY))
            log_msg = (
                "Input JSON for MCCS Subarray Leaf Node Configure command is: "
                + argin)
            self.logger.debug(log_msg)

            configuration_string = json.loads(argin)
            cmd_data = self.create_cmd_data(configuration_string)

            # Invoke Configure command on MCCSSubarray.
            log_msg = "Output Configure JSON is: " + cmd_data
            self.logger.info(log_msg)
            mccs_subarray_client.send_command_async(
                const.CMD_CONFIGURE, cmd_data, self.configure_cmd_ended_cb)
            this_server.write_attr("activityMessage",
                                   const.STR_CONFIGURE_SUCCESS, False)

            self.logger.info(const.STR_CONFIGURE_SUCCESS)

        except AssertionError:
            obsState_val = mccs_subarray_client.get_attribute("obsState").value
            log_msg = (f"Mccs Subarray is in ObsState {obsState_val}."
                       "Unable to invoke Configure command")
            device_data._read_activity_message = log_msg
            self.logger.exception(log_msg)
            tango.Except.throw_exception(
                const.STR_CONFIGURE_EXEC, log_msg,
                "MccsSubarrayLeafNode.ConfigureCommand", tango.ErrSeverity.ERR)

        except ValueError as value_error:
            log_msg = f"{const.ERR_INVALID_JSON_CONFIG}{value_error}"
            this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(value_error)
            tango.Except.throw_exception(
                const.ERR_CONFIGURE_INVOKING_CMD,
                log_msg,
                "MccsSubarrayLeafNode.Configure",
                tango.ErrSeverity.ERR,
            )

        except KeyError as key_error:
            log_msg = f"{const.ERR_JSON_KEY_NOT_FOUND}{key_error}"
            this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(key_error)
            tango.Except.throw_exception(
                const.ERR_CONFIGURE_INVOKING_CMD,
                log_msg,
                "MccsSubarrayLeafNode.Configure",
                tango.ErrSeverity.ERR,
            )

        except DevFailed as dev_failed:
            log_msg = f"{const.ERR_CONFIGURE_INVOKING_CMD}{dev_failed}"
            this_server.write_attr("activityMessage", log_msg, False)
            self.logger.exception(dev_failed)
            tango.Except.throw_exception(
                const.ERR_CONFIGURE_INVOKING_CMD,
                log_msg,
                "MccsSubarrayLeafNode.Configure",
                tango.ErrSeverity.ERR,
            )