.. currentmodule:: PyTango.server .. _pytango-hlapi: High level server API ===================== .. automodule:: PyTango.server .. hlist:: * :class:`~PyTango.server.Device` * :class:`~PyTango.server.attribute` * :class:`~PyTango.server.command` * :class:`~PyTango.server.device_property` * :class:`~PyTango.server.class_property` * :func:`~PyTango.server.run` * :func:`~PyTango.server.server_run` This module provides a high level device server API. It implements :ref:`TEP1 `. It exposes an easier API for developing a Tango device server. Here is a simple example on how to write a *Clock* device server using the high level API:: import time from PyTango.server import run from PyTango.server import Device, DeviceMeta from PyTango.server import attribute, command class Clock(Device): __metaclass__ = DeviceMeta time = attribute() def read_time(self): return time.time() @command(din_type=str, dout_type=str) def strftime(self, format): return time.strftime(format) if __name__ == "__main__": run((Clock,)) Here is a more complete example on how to write a *PowerSupply* device server using the high level API. The example contains: #. a read-only double scalar attribute called *voltage* #. a read/write double scalar expert attribute *current* #. a read-only double image attribute called *noise* #. a *ramp* command #. a *host* device property #. a *port* class property .. code-block:: python :linenos: from time import time from numpy.random import random_sample from PyTango import AttrQuality, AttrWriteType, DispLevel, server_run from PyTango.server import Device, DeviceMeta, attribute, command from PyTango.server import class_property, device_property class PowerSupply(Device): __metaclass__ = DeviceMeta voltage = attribute() current = attribute(label="Current", dtype=float, display_level=DispLevel.EXPERT, access=AttrWriteType.READ_WRITE, unit="A", format="8.4f", min_value=0.0, max_value=8.5, min_alarm=0.1, max_alarm=8.4, min_warning=0.5, max_warning=8.0, fget="get_current", fset="set_current", doc="the power supply current") noise = attribute(label="Noise", dtype=((float,),), max_dim_x=1024, max_dim_y=1024, fget="get_noise") host = device_property(dtype=str) port = class_property(dtype=int, default_value=9788) def read_voltage(self): self.info_stream("get voltage(%s, %d)" % (self.host, self.port)) return 10.0 def get_current(self): return 2.3456, time(), AttrQuality.ATTR_WARNING def set_current(self, current): print("Current set to %f" % current) def get_noise(self): return random_sample((1024, 1024)) @command(dtype_in=float) def ramp(self, value): print("Ramping up...") if __name__ == "__main__": server_run((PowerSupply,)) *Pretty cool, uh?* .. note:: the ``__metaclass__`` statement is mandatory due to a limitation in the *boost-python* library used by PyTango. If you are using python 3 you can write instead:: class PowerSupply(Device, metaclass=DeviceMeta) pass .. _pytango-hlapi-datatypes: .. rubric:: Data types When declaring attributes, properties or commands, one of the most important information is the data type. It is given by the keyword argument *dtype*. In order to provide a more *pythonic* interface, this argument is not restricted to the :obj:`~PyTango.CmdArgType` options. For example, to define a *SCALAR* :obj:`~PyTango.CmdArgType.DevLong` attribute you have several possibilities: #. :obj:`int` #. 'int' #. 'int32' #. 'integer' #. :obj:`PyTango.CmdArgType.DevLong` #. 'DevLong' #. :obj:`numpy.int32` To define a *SPECTRUM* attribute simply wrap the scalar data type in any python sequence: * using a *tuple*: ``(:obj:`int`,)`` or * using a *list*: ``[:obj:`int`]`` or * any other sequence type To define an *IMAGE* attribute simply wrap the scalar data type in any python sequence of sequences: * using a *tuple*: ``((:obj:`int`,),)`` or * using a *list*: ``[[:obj:`int`]]`` or * any other sequence type Below is the complete table of equivalences. ======================================== ======================================== dtype argument converts to tango type ======================================== ======================================== ``None`` ``DevVoid`` ``'None'`` ``DevVoid`` ``DevVoid`` ``DevVoid`` ``'DevVoid'`` ``DevVoid`` ``DevState`` ``DevState`` ``'DevState'`` ``DevState`` :py:obj:`bool` ``DevBoolean`` ``'bool'`` ``DevBoolean`` ``'boolean'`` ``DevBoolean`` ``DevBoolean`` ``DevBoolean`` ``'DevBoolean'`` ``DevBoolean`` :py:obj:`numpy.bool_` ``DevBoolean`` ``'char'`` ``DevUChar`` ``'chr'`` ``DevUChar`` ``'byte'`` ``DevUChar`` ``chr`` ``DevUChar`` ``DevUChar`` ``DevUChar`` ``'DevUChar'`` ``DevUChar`` :py:obj:`numpy.uint8` ``DevUChar`` ``'int16'`` ``DevShort`` ``DevShort`` ``DevShort`` ``'DevShort'`` ``DevShort`` :py:obj:`numpy.int16` ``DevShort`` ``'uint16'`` ``DevUShort`` ``DevUShort`` ``DevUShort`` ``'DevUShort'`` ``DevUShort`` :py:obj:`numpy.uint16` ``DevUShort`` :py:obj:`int` ``DevLong`` ``'int'`` ``DevLong`` ``'int32'`` ``DevLong`` ``DevLong`` ``DevLong`` ``'DevLong'`` ``DevLong`` :py:obj:`numpy.int32` ``DevLong`` ``'uint'`` ``DevULong`` ``'uint32'`` ``DevULong`` ``DevULong`` ``DevULong`` ``'DevULong'`` ``DevULong`` :py:obj:`numpy.uint32` ``DevULong`` ``'int64'`` ``DevLong64`` ``DevLong64`` ``DevLong64`` ``'DevLong64'`` ``DevLong64`` :py:obj:`numpy.int64` ``DevLong64`` ``'uint64'`` ``DevULong64`` ``DevULong64`` ``DevULong64`` ``'DevULong64'`` ``DevULong64`` :py:obj:`numpy.uint64` ``DevULong64`` ``DevInt`` ``DevInt`` ``'DevInt'`` ``DevInt`` ``'float32'`` ``DevFloat`` ``DevFloat`` ``DevFloat`` ``'DevFloat'`` ``DevFloat`` :py:obj:`numpy.float32` ``DevFloat`` :py:obj:`float` ``DevDouble`` ``'double'`` ``DevDouble`` ``'float'`` ``DevDouble`` ``'float64'`` ``DevDouble`` ``DevDouble`` ``DevDouble`` ``'DevDouble'`` ``DevDouble`` :py:obj:`numpy.float64` ``DevDouble`` :py:obj:`str` ``DevString`` ``'str'`` ``DevString`` ``'string'`` ``DevString`` ``'text'`` ``DevString`` ``DevString`` ``DevString`` ``'DevString'`` ``DevString`` :py:obj:`bytearray` ``DevEncoded`` ``'bytearray'`` ``DevEncoded`` ``'bytes'`` ``DevEncoded`` ``DevEncoded`` ``DevEncoded`` ``'DevEncoded'`` ``DevEncoded`` ``DevVarBooleanArray`` ``DevVarBooleanArray`` ``'DevVarBooleanArray'`` ``DevVarBooleanArray`` ``DevVarCharArray`` ``DevVarCharArray`` ``'DevVarCharArray'`` ``DevVarCharArray`` ``DevVarShortArray`` ``DevVarShortArray`` ``'DevVarShortArray'`` ``DevVarShortArray`` ``DevVarLongArray`` ``DevVarLongArray`` ``'DevVarLongArray'`` ``DevVarLongArray`` ``DevVarLong64Array`` ``DevVarLong64Array`` ``'DevVarLong64Array'`` ``DevVarLong64Array`` ``DevVarULong64Array`` ``DevVarULong64Array`` ``'DevVarULong64Array'`` ``DevVarULong64Array`` ``DevVarFloatArray`` ``DevVarFloatArray`` ``'DevVarFloatArray'`` ``DevVarFloatArray`` ``DevVarDoubleArray`` ``DevVarDoubleArray`` ``'DevVarDoubleArray'`` ``DevVarDoubleArray`` ``DevVarUShortArray`` ``DevVarUShortArray`` ``'DevVarUShortArray'`` ``DevVarUShortArray`` ``DevVarULongArray`` ``DevVarULongArray`` ``'DevVarULongArray'`` ``DevVarULongArray`` ``DevVarStringArray`` ``DevVarStringArray`` ``'DevVarStringArray'`` ``DevVarStringArray`` ``DevVarLongStringArray`` ``DevVarLongStringArray`` ``'DevVarLongStringArray'`` ``DevVarLongStringArray`` ``DevVarDoubleStringArray`` ``DevVarDoubleStringArray`` ``'DevVarDoubleStringArray'`` ``DevVarDoubleStringArray`` ======================================== ======================================== .. autoclass:: Device :show-inheritance: :inherited-members: :members: .. autoclass:: attribute .. autofunction:: command .. autoclass:: device_property .. autoclass:: class_property .. autofunction:: run .. autofunction:: server_run