Commit 580e6f3c authored by Milan Prica's avatar Milan Prica

As currently deployed at FERMI.

parents
NAME = smaractmcs_ne-srv
MAIN = Smaract_mcs_ne.py
DIRNAME = $(NAME:-srv=)
MODNAME = $(MAIN:.py=)
PY_FILES += $(wildcard src/*.py)
default: bin ${PY_FILES}
@cp ${PY_FILES} bin/${DIRNAME}
@echo "#!/usr/bin/env python\nimport sys\nsys.path.append(sys.path[0]+'/${DIRNAME}')\nfrom ${MODNAME} import main\nif __name__ == '__main__':\n main()\n" > bin/${NAME}
@chmod +x bin/${NAME} bin/${DIRNAME}/${MAIN}
bin:
@test -d $@ || mkdir -p $@/${DIRNAME}
clean:
@rm -fr bin/ src/*~
.PHONY: clean
# SmarAct MCS Tango device server for encoder-less positioners.
There are two separate versions of the device server, one for positioners
with encoder (sensor) and the other for those without encoder (sensorless)
as their behaviour differs considerably.
A MCS controller can control a number of positioners of both types.
Typical installation consists of a socket-srv device server connected to the
controller and an instance of the appropriate Smaract server per positioner.
#!/usr/bin/env python
# -*- coding:utf-8 -*-
##############################################################################
## license :
##============================================================================
##
## File : Smaract_mcs_ne.py
##
## Project :
##
## This file is part of Tango device class.
##
## Tango is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## Tango is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Tango. If not, see <http://www.gnu.org/licenses/>.
##
##
## $Author : sci-comp$
##
## $Revision : $
##
## $Date : $
##
## $HeadUrl : $
##============================================================================
## This file is generated by POGO
## (Program Obviously used to Generate tango Object)
##
## (c) - Software Engineering Group - ESRF
##############################################################################
"""SmarAct MCS controller for motors without encoder (sensor)."""
__all__ = ["Smaract_mcs_ne", "Smaract_mcs_neClass", "main"]
__docformat__ = 'restructuredtext'
import PyTango
import sys
# Add additional import
#----- PROTECTED REGION ID(Smaract_mcs_ne.additionnal_import) ENABLED START -----#
import time
# SENSOR_TYPE_SR2 = 23 # rotary positioner with nano sensor for high applied masses
BEGIN_OF_LINE = ':'
END_OF_LINE = '\012'
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.additionnal_import
## Device States Description
## ON :
## OFF :
## FAULT :
## INIT :
## ALARM :
## MOVING :
## UNKNOWN :
class Smaract_mcs_ne (PyTango.Device_4Impl):
#--------- Add you global variables here --------------------------
#----- PROTECTED REGION ID(Smaract_mcs_ne.global_variables) ENABLED START -----#
#------------------------------------------------------------------
# Read/write socket utility
# Returns a string in case of a proper reply,
# 0 for no reply or failure.
#------------------------------------------------------------------
def socket_write_and_read(self, argin):
# print "In ", self.get_name(), "::socket_write_and_read()"
# self.debug_stream("argin: " + str(argin))
mcs_cmd = BEGIN_OF_LINE + str(argin) + END_OF_LINE
attempts = 0
max_attempts = 2 # In case of a socket exception, retry once.
while (attempts < max_attempts):
try:
argout = self.socket.WriteAndRead(mcs_cmd)
if len(argout) == 0:
self.status_string = "Cmd failed, no reply." # We ARE in the 'Sync' mode.
self.debug_stream(self.status_string)
return 0
# Strip the BEGIN_OF_LINE and END_OF_LINE characters from the response.
argout = argout[1:-1]
# self.debug_stream("argout: " + str(argout))
if argout.startswith('E'):
try:
err_code = int(str.split(argout, ',')[1])
except Exception, e:
print e
return 0
if err_code == 0:
# self.status_string = "Cmd " + str(argin) + " successfully executed.\n"
return argout
else:
err_type, err_desc = self.get_error_msg(err_code)
self.status_string = "Cmd failed with " + err_type
self.attr_Error_read = err_type + " : " + err_desc
self.debug_stream(self.status_string)
self.error_msg_timer = time.time()
return 0
else:
# self.status_string = "Cmd " + str(argin) + " successfully executed.\n"
return argout
except Exception, e:
print "Socket connection raised exception.\n"
attempts += 1
self.status_string = "Socket Failed: "+str(e)
time.sleep(0.1)
# Socket problem persists, set state to FAULT
self.set_state(PyTango.DevState.FAULT)
return 0
#------------------------------------------------------------------
# Get MCS error type utility
# argin = error code (int)
# Returns a string with error type and description,
# None if error code is not valid.
#------------------------------------------------------------------
def get_error_msg(self, argin):
error_type = {
0 : "No Error",
1 : "Syntax Error",
2 : "Invalid Command Error",
3 : "Overflow Error",
4 : "Parse Error",
5 : "Too Few Parameters Error",
6 : "Too Many Parameters Error",
7 : "Invalid Parameter Error",
8 : "Wrong Mode Error",
129 : "No Sensor Present Error",
140 : "Sensor Disabled Error",
141 : "Command Overridden Error",
142 : "End Stop Reached Error",
143 : "Wrong Sensor Type Error",
144 : "Could Not Find Reference Mark Error",
145 : "Wrong End Effector Type Error",
146 : "Movement Locked Error",
147 : "Range Limit Reached Error",
148 : "Physical Position Unknown Error",
150 : "Command Not Processable Error",
151 : "Waiting For Trigger Error",
152 : "Command Not Triggerable Error",
153 : "Command Queue Full Error",
154 : "Invalid Component Error",
155 : "Invalid Sub Component Error",
156 : "Invalid Property Error",
157 : "Permission Denied Error"
}
error_desc = {
0 : "This indicates that no error occurred and therefore corresponds to an acknowledge.",
1 : "The command could not be processed due to a syntactical error.",
2 : "The command given is not known to the system.",
3 : "This error occurs if a parameter given is too large and therefore cannot be processed.",
4 : "The command could not be processed due to a parse error.",
5 : "The specified command requires more parameters in order to be executed.",
6 : "There were too many parameters given for the specified command.",
7 : "A parameter given exceeds the valid range. Please see the command description "\
"for valid ranges of the parameters.",
8 : "This error is generated if the specified command is not available in the "\
"current communication mode. "\
"For example, the SRC command is not executable in synchronous mode.",
129 : "This error occurs if a command was given that requires sensor feedback, "\
"but the addressed positioner has none attached.",
140 : "This error occurs if a command was given that requires sensor feedback, "\
"but the sensor of the addressed positioner is disabled (see SSE command).",
141 : "This error is only generated in the asynchronous communication mode. "\
"When the software commands a movement which is then interrupted by the "\
"Hand Control Module, an error of this type is generated.",
142 : "This error is generated in asynchronous mode if the target position of a "\
"closed-loop command could not be reached, because a mechanical end stop was detected. "\
"After this error the positioner will have a movement status code of 0 (stopped).",
143 : "This error occurs if a closed-loop command does not match the sensor type that "\
"is currently configured for the addressed channel. For example, issuing a GP "\
"command while the targeted channel is configured as rotary will lead to this error.",
144 : "This error is generated in asynchronous mode (see SCM ) if the search "\
"for a reference mark was aborted.",
145 : "This error occurs if a command does not match the end effector type that is currently "\
"configured for the addressed channel. For example, sending GF while the targeted channel "\
"is configured for a gripper will lead to this error.",
146 : "This error occurs if a movement command is issued while the system is in the locked state.",
147 : "If a range limit is defined (SPL or SAL ) and the positioner is about to move beyond "\
"this limit, then the positioner will stop and report this error (only in asynchronous mode, "\
"see SCM ). After this error the positioner will have status code of 0 (stopped).",
148 : "A range limit is only allowed to be defined if the positioner knows its physical position. "\
"If this is not the case, the commands SPL and SAL will return this error code.",
150 : "This error is generated if a command is sent to a channel when it is in a state where the "\
"command cannot be processed. For example, to change the sensor type of a channel the addressed "\
"channel must be completely stopped. In this case send a stop command before changing the type.",
151 : "If there is at least one command queued in the command queue then you may only append more "\
"commands (if the queue is not full), but you may not issue movement commands for immediate "\
"execution. Doing so will generate this error. ",
152 : "After sending a ATC command you are required to issue a movement command that is to be "\
"triggered by the given event source. Commands that cannot be triggered will generate this error.",
153 : "This error is generated if you attempt to append more commands to the command queue, "\
"but the queue cannot hold anymore commands. The queue capacity may be read out with a "\
"get channel property command (GCP).",
154 : "Indicates that a component (e.g. SCP) was selected that does not exist.",
155 : "Indicates that a sub component (e.g. SCP) was selected that does not exist.",
156 : "Indicates that a property (e.g. SCP) was selected that does not exist.",
157 : "This error is generated when you call a functionality which is not unlocked "\
"for the system (e.g. Low Vibration Mode)."
}
if argin in error_type:
return error_type[argin], error_desc[argin]
else:
return None
#------------------------------------------------------------------
# Get movement status utility
# argin = movement status code (int), as returned by the GS command.
# Returns a string with error type and description,
# None if error code is not valid.
#------------------------------------------------------------------
def get_movement_status(self, argin):
channel_status = {
0 : "Stopped - The positioner is currently not performing active movement (see S command).",
1 : "Stepping - The positioner is performing an open-loop movement (see MST command).",
2 : "Scanning - The positioner is performing a scanning movement (see commands MSCA and MSCR).",
3 : "Holding - The positioner is holding its current target position resp. angle (see closed-loop"\
"commands, e.g. MPA or MAA) or is holding the reference mark (see FRM command).",
4 : "Targeting - The positioner is performing a closed-loop movement "\
"(see closed-loop commands, e.g. MPA or MAA).",
5 : "Move Delay - The positioner is currently waiting for the sensors to power up before executing the"\
"movement command. This status may be returned if the the sensors are operated in power save mode.",
6 : "Calibrating - The positioner is busy calibrating its sensor (see commands CS and SZF).",
7 : "Finding Reference Mark - The positioner is moving to find the reference mark (see FRM command).",
9 : "Locked - An emergency stop has occurred and further movements are not allowed (see SESMcommand)."
}
if argin in channel_status:
return channel_status[argin]
else:
return None
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.global_variables
def __init__(self,cl, name):
PyTango.Device_4Impl.__init__(self,cl,name)
self.debug_stream("In __init__()")
Smaract_mcs_ne.init_device(self)
#----- PROTECTED REGION ID(Smaract_mcs_ne.__init__) ENABLED START -----#
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.__init__
def delete_device(self):
self.debug_stream("In delete_device()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.delete_device) ENABLED START -----#
self.stop_polling()
del self.socket
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.delete_device
def init_device(self):
self.debug_stream("In init_device()")
self.get_device_properties(self.get_device_class())
self.attr_Steps_read = 0
self.attr_Velocity_read = 0
self.attr_MotorTitle_read = ""
self.attr_Position_read = 0
self.attr_Voltage_read = 0
self.attr_Error_read = ''
#----- PROTECTED REGION ID(Smaract_mcs_ne.init_device) ENABLED START -----#
self.set_state(PyTango.DevState.INIT)
self.status_string = "Initializing device..."
try:
# socket device to SmarAct MCS Controller
self.socket = PyTango.DeviceProxy(self.SocketDevice)
if self.socket.state() != PyTango.DevState.ON:
self.set_state(PyTango.DevState.FAULT)
self.status_string = "Socket device not in ON state. INIT failed."
return
except PyTango.DevFailed:
exctype, value = sys.exc_info()[:2]
print "Failed with exception ! ", exctype
for err in value:
print " reason", err.reason
print " description", err.desc
print " origin", err.origin
print " severity", err.severity
self.set_state(PyTango.DevState.FAULT)
self.status_string = "INIT failed, Socket proxy failed."
self.debug_stream(self.status_string)
return
self.debug_stream("Channel: "+str(self.ChannelIndex))
# self.debug_stream("SensorType: "+str(self.SensorType))
# Set Communication Mode to Sync (0) (Alt. Async(1))
resp = self.socket_write_and_read("GCM")
if resp == 0:
self.debug_stream(self.attr_Error_read)
self.set_state(PyTango.DevState.FAULT)
PyTango.Except.throw_exception("Set Communication Mode to Sync failed.", self.status_string, "init_device()")
else:
try:
# Expected repy is CM0 or CM1
comm_mode = int(resp[-1])
except Exception, e:
PyTango.Except.throw_exception("Set Communication Mode to Sync failed.", "Unexpected reply format", "init_device()")
self.debug_stream('Communication mode:'+str(comm_mode))
if comm_mode <> 0:
self.debug_stream('Communication mode is not 0 (Sync), set it to sync.')
# Set Communication Mode to Sync (0) (Alt. Async(1))
resp = self.socket_write_and_read("SCM0")
if resp == 0:
self.debug_stream(self.attr_Error_read)
self.set_state(PyTango.DevState.FAULT)
PyTango.Except.throw_exception("Set Communication Mode to Sync failed.", self.status_string, "init_device()")
else:
self.debug_stream("init_device(): Sync Communication Mode set (for all channels).")
# Check Sensor type:
cmd_str = "GST"+str(self.ChannelIndex)
resp = self.socket_write_and_read(cmd_str)
if resp == 0:
# raise Exception("Incorrect request, check socket status.")
self.set_state(PyTango.DevState.FAULT)
self.debug_stream(self.status_string)
PyTango.Except.throw_exception("Get Sensor Type failed.", self.status_string, "init_device()")
else:
try:
stype = int(str.split(resp, ',')[1])
except Exception, e:
PyTango.Except.throw_exception("Get Sensor Type failed.", "Unexpected reply format", "init_device()")
# self.debug_stream("Sensor Type:"+str(stype))
# if stype != self.SensorType:
# # Set Sensor type (property SensorType)
# cmd_str = "SST"+str(self.ChannelIndex)+","+str(SENSOR_TYPE_SR2)
# resp = self.socket_write_and_read(cmd_str)
# if resp == 0:
# # raise Exception("Incorrect request, check socket status.")
# self.set_state(PyTango.DevState.FAULT)
# self.debug_stream(self.status_string)
# PyTango.Except.throw_exception("Set Sensor Type failed.", self.status_string, "init_device()")
# Check Power Save Mode
resp = self.socket_write_and_read("GSE")
if resp == 0:
self.debug_stream(self.attr_Error_read)
self.set_state(PyTango.DevState.FAULT)
PyTango.Except.throw_exception("Get Sensors Enabled failed.", self.status_string, "init_device()")
else:
try:
# expected reply SE<0/1/2>
sensor_enabled = int(resp[-1])
except Exception, e:
PyTango.Except.throw_exception("Get Sensors Enabled failed.", "Unexpected reply format", "init_device()")
self.debug_stream('Sensor enabled: '+str(sensor_enabled))
if sensor_enabled <> 2:
# Enable sensor, set to Power Save mode.
if self.socket_write_and_read("SSE2") == 0:
self.debug_stream(self.attr_Error_read)
self.set_state(PyTango.DevState.FAULT)
PyTango.Except.throw_exception("Enable Sensor in Power Save Mode failed", self.status_string, "init_device()")
else:
self.debug_stream("init_device(): Sensor enabled in power save mode (for all channels).")
self.set_status(self.status_string)
if self.get_state() is PyTango.DevState.INIT:
self.set_state(PyTango.DevState.ON)
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.init_device
def always_executed_hook(self):
# self.debug_stream("In always_excuted_hook()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.always_executed_hook) ENABLED START -----#
if self.socket.state() != PyTango.DevState.ON:
self.set_state(PyTango.DevState.FAULT)
self.status_string = "Socket device not in ON state, check connection."
else:
cmd_str = "GS"+str(self.ChannelIndex)
resp = self.socket_write_and_read(cmd_str)
if resp == 0:
self.debug_stream(self.attr_Error_read)
self.set_state(PyTango.DevState.ALARM)
else:
try:
status_code = int(str.split(resp,',')[1])
self.status_string = self.get_movement_status(status_code)
if status_code in [0,3,5]:
self.set_state(PyTango.DevState.ON)
elif status_code in [1,2,4,6,7]:
self.set_state(PyTango.DevState.MOVING)
elif status_code == 9:
self.set_state(PyTango.DevState.ALARM)
else:
self.set_state(PyTango.DevState.UNKNOWN)
except Exception, e:
self.set_state(PyTango.DevState.ALARM)
self.status_string = "Failed parsing the controller status."
self.set_status(self.status_string)
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.always_executed_hook
#-----------------------------------------------------------------------------
# Smaract_mcs_ne read/write attribute methods
#-----------------------------------------------------------------------------
def read_Steps(self, attr):
# self.debug_stream("In read_Steps()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.Steps_read) ENABLED START -----#
attr.set_value(self.attr_Steps_read)
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Steps_read
def write_Steps(self, attr):
# self.debug_stream("In write_Steps()")
data=attr.get_write_value()
#----- PROTECTED REGION ID(Smaract_mcs_ne.Steps_write) ENABLED START -----#
self.attr_Steps_read = data
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Steps_write
def read_Velocity(self, attr):
# self.debug_stream("In read_Velocity()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.Velocity_read) ENABLED START -----#
attr.set_value(self.attr_Velocity_read)
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Velocity_read
def write_Velocity(self, attr):
# self.debug_stream("In write_Velocity()")
data=attr.get_write_value()
#----- PROTECTED REGION ID(Smaract_mcs_ne.Velocity_write) ENABLED START -----#
self.attr_Velocity_read = data
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Velocity_write
def read_MotorTitle(self, attr):
# self.debug_stream("In read_MotorTitle()")
#----- PROTECTED REGION ID(Smaract_mcs.MotorTitle_read) ENABLED START -----#
attr.set_value(self.attr_MotorTitle_read)
#----- PROTECTED REGION END -----# // Smaract_mcs.MotorTitle_read
def write_MotorTitle(self, attr):
# self.debug_stream("In write_MotorTitle()")
data=attr.get_write_value()
#----- PROTECTED REGION ID(Smaract_mcs.MotorTitle_write) ENABLED START -----#
self.attr_MotorTitle_read = data
#----- PROTECTED REGION END -----# // Smaract_mcs.MotorTitle_write
def read_Position(self, attr):
# self.debug_stream("In read_Position()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.Position_read) ENABLED START -----#
attr.set_value(self.attr_Position_read)
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Position_read
def write_Position(self, attr):
# self.debug_stream("In write_Position()")
data = attr.get_write_value()
#----- PROTECTED REGION ID(Smaract_mcs_ne.Position_write) ENABLED START -----#
self.attr_Steps_read = int(abs(data - self.attr_Position_read))
if data >= self.attr_Position_read:
self.StepUp()
else:
self.StepDown()
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Position_write
def read_Voltage(self, attr):
# self.debug_stream("In read_Voltage()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.Voltage_read) ENABLED START -----#
attr.set_value(self.attr_Voltage_read)
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Voltage_read
def write_Voltage(self, attr):
# self.debug_stream("In write_Voltage()")
data=attr.get_write_value()
#----- PROTECTED REGION ID(Smaract_mcs_ne.Voltage_write) ENABLED START -----#
self.attr_Voltage_read = data
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Voltage_write
def read_Error(self, attr):
# self.debug_stream("In read_Error()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.Error_read) ENABLED START -----#
attr.set_value(self.attr_Error_read)
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Error_read
#----- PROTECTED REGION ID(Smaract_mcs_ne.initialize_dynamic_attributes) ENABLED START -----#
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.initialize_dynamic_attributes
def read_attr_hardware(self, data):
# self.debug_stream("In read_attr_hardware()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.read_attr_hardware) ENABLED START -----#
return
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.read_attr_hardware
#-----------------------------------------------------------------------------
# Smaract_mcs_ne command methods
#-----------------------------------------------------------------------------
def StepUp(self):
""" Move in the positive direction with Steps, Velocity and Voltage attributes as parameters.
:param :
:type: PyTango.DevVoid
:return:
:rtype: PyTango.DevVoid """
# self.debug_stream("In StepUp()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.StepUp) ENABLED START -----#
cmd_str = "MST"+str(self.ChannelIndex)+','+str(self.attr_Steps_read)+','+str(self.attr_Voltage_read)+','+str(self.attr_Velocity_read)
print 'StepUp:', cmd_str
resp = self.socket_write_and_read(cmd_str)
if resp == 0:
self.debug_stream(self.attr_Error_read)
PyTango.Except.throw_exception("Cmd StepUp Failed", self.status_string, "StepUp()")
else:
self.attr_Position_read += self.attr_Steps_read
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.StepUp
def is_StepUp_allowed(self):
return self.get_state() in (PyTango.DevState.ON,)
def StepDown(self):
""" Move in the negative direction with Steps, Velocity and Voltage attributes as parameters.
:param :
:type: PyTango.DevVoid
:return:
:rtype: PyTango.DevVoid """
# self.debug_stream("In StepDown()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.StepDown) ENABLED START -----#
cmd_str = "MST"+str(self.ChannelIndex)+','+str(-1*self.attr_Steps_read)+','+str(self.attr_Voltage_read)+','+str(self.attr_Velocity_read)
print 'StepDown:', cmd_str
resp = self.socket_write_and_read(cmd_str)
if resp == 0:
self.debug_stream(self.attr_Error_read)
PyTango.Except.throw_exception("Cmd StepDown Failed", self.status_string, "StepDown()")
else:
self.attr_Position_read -= self.attr_Steps_read
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.StepDown
def is_StepDown_allowed(self):
return self.get_state() in (PyTango.DevState.ON,)
def Move(self, argin):
""" Move by a given number of steps. Sign determines the direction.
:param argin: Steps
:type: PyTango.DevShort
:return:
:rtype: PyTango.DevVoid """
# self.debug_stream("In Move()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.Move) ENABLED START -----#
cmd_str = "MST"+str(self.ChannelIndex)+','+str(argin)+','+str(self.attr_Voltage_read)+','+str(self.attr_Velocity_read)
print 'Move:', cmd_str
resp = self.socket_write_and_read(cmd_str)
if resp == 0:
self.debug_stream(self.attr_Error_read)
PyTango.Except.throw_exception("Cmd Move Failed", self.status_string, "Move()")
else:
self.attr_Position_read += argin
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Move
def is_Move_allowed(self):
return self.get_state() in (PyTango.DevState.ON,)
def Stop(self):
""" Stop the motion.
:param :
:type: PyTango.DevVoid
:return:
:rtype: PyTango.DevVoid """
# self.debug_stream("In Stop()")
#----- PROTECTED REGION ID(Smaract_mcs_ne.Stop) ENABLED START -----#
cmd_str = "S"+str(self.ChannelIndex)
resp = self.socket_write_and_read(cmd_str)
if resp == 0:
self.debug_stream(self.attr_Error_read)
PyTango.Except.throw_exception("Cmd Stop Failed", self.status_string, "Stop()")
#----- PROTECTED REGION END -----# // Smaract_mcs_ne.Stop