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
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.")
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")
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, )
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, )
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, )
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, )
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, )
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, )