High level server APIΒΆ

  • Device
  • attribute
  • command
  • pipe
  • device_property
  • class_property
  • run()
  • server_run()

This module provides a high level device server API. It implements 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 tango.server import run
from tango.server import Device
from tango.server import attribute, command


class Clock(Device):

    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:

  1. a read-only double scalar attribute called voltage
  2. a read/write double scalar expert attribute current
  3. a read-only double image attribute called noise
  4. a ramp command
  5. a host device property
  6. a port class property
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from time import time
from numpy.random import random_sample

from tango import AttrQuality, AttrWriteType, DispLevel
from tango.server import Device, attribute, command
from tango.server import class_property, device_property

class PowerSupply(Device):

    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__":
    PowerSupply.run_server()

Pretty cool, uh?

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 CmdArgType options.

For example, to define a SCALAR DevLong attribute you have several possibilities:

  1. int
  2. ‘int’
  3. ‘int32’
  4. ‘integer’
  5. tango.CmdArgType.DevLong
  6. ‘DevLong’
  7. 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
bool DevBoolean
'bool' DevBoolean
'boolean' DevBoolean
DevBoolean DevBoolean
'DevBoolean' DevBoolean
numpy.bool_ DevBoolean
'char' DevUChar
'chr' DevUChar
'byte' DevUChar
chr DevUChar
DevUChar DevUChar
'DevUChar' DevUChar
numpy.uint8 DevUChar
'int16' DevShort
DevShort DevShort
'DevShort' DevShort
numpy.int16 DevShort
'uint16' DevUShort
DevUShort DevUShort
'DevUShort' DevUShort
numpy.uint16 DevUShort
int DevLong
'int' DevLong
'int32' DevLong
DevLong DevLong
'DevLong' DevLong
numpy.int32 DevLong
'uint' DevULong
'uint32' DevULong
DevULong DevULong
'DevULong' DevULong
numpy.uint32 DevULong
'int64' DevLong64
DevLong64 DevLong64
'DevLong64' DevLong64
numpy.int64 DevLong64
'uint64' DevULong64
DevULong64 DevULong64
'DevULong64' DevULong64
numpy.uint64 DevULong64
DevInt DevInt
'DevInt' DevInt
'float32' DevFloat
DevFloat DevFloat
'DevFloat' DevFloat
numpy.float32 DevFloat
float DevDouble
'double' DevDouble
'float' DevDouble
'float64' DevDouble
DevDouble DevDouble
'DevDouble' DevDouble
numpy.float64 DevDouble
str DevString
'str' DevString
'string' DevString
'text' DevString
DevString DevString
'DevString' DevString
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
DevPipeBlob DevPipeBlob
'DevPipeBlob' DevPipeBlob