# Reference part

Intended audience: developers, Programming language: all

This chapter is only part of the TANGO device server reference guide. To get reference documentation about the C++ library classes, see [TangoRefMan] To get reference documentation about the Java classes, also see [TangoRefMan]

## Device parameter

A black box, a device description field, a device state and status are associated with each TANGO device.

### The device black box

The device black box is managed as a circular buffer. It is possible to tune the buffer depth via a device property. This property name is

device name->blackbox_depth

A default value is hard-coded to 50 if the property is not defined. This black box depth property is retrieved from the Tango property database during the device creation phase.

### The device description field

There are two ways to intialise the device description field.

- At device creation time. Some constructors of the DeviceImpl class supports this field as parameter. If these constructor are not used, the device description field is set to a default value which is A Tango device.

- With a property. A description field defines with this method overrides a device description defined at construction time. The property name is

  device name->description

### The device state and status

Some constructors of the DeviceImpl class allows the initialisation of device state and/or status or device creation time. If these fields are not defined, a default value is applied. The default state is Tango::UNKOWN, the default status is Not Initialised.

### The device polling

Seven device properties allow the polling tunning. These properties are described in the following table

Property name | property rule | default value
--- | --- | ---
poll_ring_depth | Polling buffer depth | 10
cmd_poll_ring_depth | Cmd polling buffer depth |
attr_poll_ring_depth | Attr polling buffer depth |
poll_old_factor | Data too old factor | 4
min_poll_period | Minimun polling period |
cmd_min_poll_period | Min. polling period for cmd |
attr_min_poll_period | Min. polling period for attr |

The rule of the poll_ring_depth property is obvious. It defines the polling ring depth for all the device polled command(s) and attribute(s). Nevertheless, when filling the polling buffer via the fill_cmd_polling_buffer() (or fill_attr_polling_buffer()) method, it could be helpfull to define specific polling ring depth for a command (or an attribute). This is the rule of the cmd_poll_ring_depth and attr_poll_ring_depth properties. For each polled object with specific polling depth (command or attribute), the syntax of this property is the object name followed by the ring depth (ie State,20,Status,15). If one of these properties is defined, for the specific command or attribute, it will overwrite the value set by the poll_ring_depth property. The poll_old_factor property allows the user to tune how long the data recorded in the polling buffer are valid. Each time some data are read from the polling buffer, a check is done between the date when the data were recorded in the polling buffer and the date when the user request these data. If the interval is greater than the object polling period multiply by the value of the poll_old_factor factory, an exception is returned to the caller. These two properties are defined at device level and therefore, it is not possible to tune this parameter for each polled object (command or attribute). The last 3 properties are dedicated to define a polling period minimum threshold. The property min_poll_period defines in (mS) a device minimum polling period. Property cmd_min_poll_period defines (in mS) a minimum polling period for a specific command. The syntax of this property is the command name followed by the minimum polling period (ie MyCmd,400). Property attr_min_poll_period defines (in mS) a minimum polling period for a specific attribute. The syntax of this property is the attribute name followed by the minimum polling period (ie MyAttr,600). These two properties has a higher priority than the min_poll_period property. By default these three properties are not defined mening that there is no minimun polling period.

Four other properties are used by the Tango core classes to manage the polling thread. These properties are :

- polled_cmd to memorize the name of the device polled command

- polled_attr to memorize the name of the device polled attribute

- non_auto_polled_cmd to memorize the name of the command which shoule not be polled automatically at the first request

- non_auto_polled_attr to memorize the name of the attribute which should not be polled automatically at the first request

You don’t have to change these properties values by yourself. They are automatically created/modified/deleted by Tango core classes.

### The device logging

The Tango Logging Service (TLS) uses device properties to control device logging at startup (static configuration). These properties are described in the following table

Property name | property rule | default value
--- | --- | ---
logging_level | Initial device logging level | WARNING
logging_target | Initial device logging target | No default
logging_rft | Logging rolling file threshold | 20 Mega bytes
logging_path | Logging file path | /tmp/tango-<logging name> or C:/tango-<logging name> (Windows)

- The logging_level property controls the initial logging level of a device. Its set of possible values is: OFF, FATAL, ERROR, WARNING, INFO or DEBUG. This property is overwritten by the verbose command line option (-v).

- The logging_target property is a multi-valued property containing the initial target list. Each entry must have the following format: target_type::target_name (where target_type is one of the supported target types and target_name, the name of the target). Supported target types are: console, file and device. For a device target, target_name must contain the name of a log consumer device (as defined in [sec:Tango-log-consumer]). For a file target, target_name is the name of the file to log to. If omitted the device’s name is used to build the file name (domain_family_member.log). Finally, target_name is ignored in the case of a console target. The TLS does not report any error occurred while trying to setup the initial targets.

  - Logging_target property example :
    logging_target = [ console, file, file::/home/me/mydevice.log, device::tmp/log/1
    In this case, the device will automatically logs to the standard output, to its default file (which is something like domain_family_member.log), to a file named mydevice.log and located in /home/me. Finally, the device logs are also sent to a log consumer device named tmp/log/1.

- The logging_rft property specifies the rolling file threshold (rft), of the device’s file targets. This threshold is expressed in Kb. When the size of a log file reaches the so-called rolling-file-threshold (rft), it is backuped as current_log_file_name + _1 and a new current_log_file_name is opened. Obviously, there is only one backup file at a time (i.e. any existing backup is destroyed before the current log file is backuped). The default threshold is 20 Mb, the minimum is 500 Kb and the maximum is 1000 Mb.

- The logging_path property overwrites the TANGO_LOG_PATH environment variable. This property can only be applied to a DServer class device and has no effect on other devices.

## Device attribute

Attribute are configured with two kind of parameters: Parameters hard-coded in source code and modifiable parameters

### Hard-coded device attribute parameters

Seven attribute parameters are defined at attribute creation time in the Tango class source code. Obviously, these parameters are not modifiable except with a new source code compilation. These parameters are

Parameter name | Parameter description
--- | ---
name | Attribute name
data_type | Attribute data type
data_format | Attribute data format
writable | Attribute read/write type
max_dim_x | Maximum X dimension
max_dim_y | Maximum Y dimension
writable_attr_name | Associated write attribute
level | Attribute display level
root_attr_name | Root attribute name

#### The Attribute data type

Thirteen data types are supported. These data types are

- Tango::DevBoolean

- Tango::DevShort

- Tango::DevLong

- Tango::DevLong64

- Tango::DevFloat

- Tango::DevDouble

- Tango::DevUChar

- Tango::DevUShort

- Tango::DevULong

- Tango::DevULong64

- Tango::DevString

- Tango::DevState

- Tango::DevEncoded

#### The attribute data format

Three data format are supported for attribute

Format | Description
--- | ---
Tango::SCALAR | The attribute value is a single number
Tango::SPECTRUM | The attribute value is a one dimension number
Tango::IMAGE | The attribute value is a two dimension number

#### The max_dim_x and max_dim_y parameters

These two parameters defined the maximum size for attributes of the SPECTRUM and IMAGE data format.

data format | max_dim_x | max_dim_y
--- | --- | ---
Tango::SCALAR | 1 | 0
Tango::SPECTRUM | User Defined | 0
Tango::IMAGE | User Defined | User Defined

For attribute of the Tango::IMAGE data format, all the data are also returned in a one dimension array. The first array is value[0],[0], array element X is value[0],[X-1], array element X+1 is value[1][0] and so forth.

#### The attribute read/write type

Tango supports four kind of read/write attribute which are :

- Tango::READ for read only attribute

- Tango::WRITE for writable attribute

- Tango::READ_WRITE for attribute which can be read and write

- Tango::READ_WITH_WRITE for a readable attribute associated to a writable attribute (For a power supply device, the current really generated is not the wanted current. To handle this, two attributes are defined which are generated_current and wanted_current. The wanted_current is a Tango::WRITE attribute. When the generated_current attribute is read, it is very convenient to also get the wanted_current attribute. This is exactly what the Tango::READ_WITH_WRITE attribute is doing)

When read, attribute values are always returned within an array even for scalar attribute. The length of this array and the meaning of its elements is detailed in the following table for scalar attribute.

Name | Array length | Array[0] | Array[1]
--- | --- | --- | ---
Tango::READ | 1 | Read value |
Tango::WRITE | 1 | Last write value |
Tango::READ_WRITE | 2 | Read value | Last write value
Tango::READ_WITH_WRITE | 2 | Read value | Associated attribute last write value

When a spectrum or image attribute is read, it is possible to code the device class in order to send only some part of the attribute data (For instance only a Region Of Interest for an image) but never more than what is defined by the attribute configuration parameters max_dim_x and max_dim_y. The number of data sent is also transferred with the data and is named dim_x and dim_y. When a spectrum or image attribute is written, it is also possible to send only some of the attribute data but always less than max_dim_x for spectrum and max_dim_x * max_dim_y for image. The following table describe how data are returned for spectrum attribute. dim_x is the data size sent by the server when the attribute is read and dim_x_w is the data size used during the last attribute write call.

Name | Array length | Array[0->dim_x-1] | Array[dim_x-> dim_x + dim_x_w -1] |
--- | --- | --- | --- | ---
Tango::READ | dim_x | Read values |  |
Tango::WRITE | dim_x_w | Last write values |  |
Tango::READ_WRITE | dim_x + dim_x_w | Read value | Last write values |
Tango::READ_WITH_WRITE | dim_x + dim_x_w | Read value | Associated attributelast write values |

The following table describe how data are returned for image attribute. dim_r is the data size sent by the server when the attribute is read (dim_x * dim_y) and dim_w is the data size used during the last attribute write call (dim_x_w * dim_y_w).

Name | Array length | Array[0->dim_r-1] | Array[dim_r->dim_r + dim_w -1]
--- | --- | --- | ---
Tango::READ | dim_r | Read values |
Tango::WRITE | dim_w | Last write values |
Tango::READ_WRITE | dim_r + dim_w | Read value | Last write values
Tango::READ_WITH_WRITE | dim_r + dim_w | Read value | Associated attributelast write values

Until a write operation has been performed, the last write value is initialized to 0 for scalar attribute of the numeriacal type, to Not Initialised for scalar string attribute and to true for scalar boolean attribute. For spectrum or image attribute, the last write value is initialized to an array of one element set to 0 for numerical type, to an array of one element set to true for boolean attribute and to an array of one element set to Not initialized for string attribute

#### The associated write attribute parameter

This parameter has a meaning only for attribute with a Tango::READ_WITH_WRITE read/write type. This is the name of the associated write attribute.

#### The attribute display level parameter

This parameter is only an help for graphical application. It is a C++ enumeration starting at 0. The code associated with each attribute display level is defined in the following table (Tango::DispLevel).

name | Value
--- | ---
Tango::OPERATOR | 0
Tango::EXPERT | 1

This parameter allows a graphical application to support two types of operation :

- An operator mode for day to day operation

- An expert mode when tuning is necessary

According to this parameter, a graphical application knows if the attribute is for the operator mode or for the expert mode.

#### The root attribute name parameter

In case the attribute is a forwarded one, this parameter is the name of the associated root attribute. In case of classical attribute, this string is set to Not specified.

### Modifiable attribute parameters

Each attribute has a configuration set of 20 modifiable parameters. These can be grouped in three different purposes:

1. General purpose parameters

2. Alarm related parameters

3. Event related parameters

#### General purpose parameters

Eight attribute parameters are modifiable at run-time via a device call or via the property database.

Parameter name | Parameter description
--- | ---
description | Attribute description
label | Attribute label
unit | Attribute unit
standard_unit | Conversion factor to MKSA unit
display_unit | The attribute unit in a printable form
format | How to print attribute value
min_value | Attribute min value
max_value | Attribute max value
enum_labels | Enumerated labels
memorized | Attribute memorization

The description parameter describes the attribute. The label parameter is used by graphical application to display a label when this attribute is used in a graphical application. The unit parameter is the attribute value unit. The standard_unit parameter is the conversion factor to get attribute value in MKSA units. Even if this parameter is a number, it is returned as a string by the device get_attribute_config call. The display_unit parameter is the string used by graphical application to display attribute unit to application user. The enum_labels parameter is defined only for attribute of the DEV_ENUM data type. This is a vector of strings with one string for each enumeration label. It is an ordered list.

##### The format attribute parameter

This parameter specifies how the attribute value should be printed. It is not valid for string attribute. This format is a string of C++ streams manipulators separated by the ; character. The supported manipulators are :

- fixed

- scientific

- uppercase

- showpoint

- showpos

- setprecision()

- setw()

Their definition are the same than for C++ streams. An example of format parameter is

`scientific;uppercase;setprecision(3)`.

A class called Tango::AttrManip has been written to handle this format string. Once the attribute format string has been retrieved from the device, its value can be printed with

`cout << Tango::AttrManip(format) << value << endl;`

##### The min_value and max_value parameters

These two parameters have a meaning only for attribute of the Tango::WRITE read/write type and for numerical data types. Trying to set the value of an attribute to something less than or equal to the min_value parameter is an error. Trying to set the value of the attribute to something more or equal to the max_value parameter is also an error. Even if these parameters are numbers, they are returned as strings by the device get_attribute_config() call.

These two parameters have no meaning for attribute with data type DevString, DevBoolean or DevState. An exception is thrown in case the user try to set them for attribute of these 3 data types.

##### The memorized attribute parameter

This parameter describes the attribute memorization. It is an enumeration with the following values:

- NOT_KNOWN : The device is too old to return this information.

- NONE : The attribute is not memorized

- MEMORIZED : The attribute is memorized

- MEMORIZED_WRITE_INIT : The attribute is memorized and the memorized value is applied at device initialization time.

#### The alarm related configuration parameters

Six alarm related attribute parameters are modifiable at run-time via a device call or via the property database.

Parameter name | Parameter description
--- | ---
min_alarm | Attribute low level alarm
max_alarm | Attribute high level alarm
min_warning | Attribute low level warning
max_warning | Attribute high level warning
delta_t | delta time for RDS alarm (mS)
delta_val | delta value for RDS alarm (absolute)

These parameters have no meaning for attribute with data type DevString, DevBoolean or DevState. An exception is thrown in case the user try to set them for attribute of these 3 data types.

##### The min_alarm and max_alarm parameters

These two parameters have a meaning only for attribute of the Tango::READ, Tango::READ_WRITE and Tango::READ_WITH_WRITE read/write type and for numerical data type. When the attribute is read, if its value is something less than or equal to the min_alarm parameter or if it is something more or equal to the max_alarm parameter, the attribute quality factor will be set to Tango::ATTR_ALARM and if the device state is Tango::ON, it is switched to Tango::ALARM. Even if these parameters are numbers, they are returned as strings by the device get_attribute_config() call.

##### The min_warning and max_warning parameters

These two parameters have a meaning only for attribute of the Tango::READ, Tango::READ_WRITE and Tango::READ_WITH_WRITE read/write type and for numerical data type. When the attribute is read, if its value is something less than or equal to the min_warning parameter or if it is something more or equal to the max_warning parameter, the attribute quality factor will be set to Tango::ATTR_WARNING and if the device state is Tango::ON, it is switched to Tango::ALARM. Even if these parameters are numbers, they are returned as strings by the device get_attribute_config() call.

##### The delta_t and delta_val parameters

These two parameters have a meaning only for attribute of the Tango::READ_WRITE and Tango::READ_WITH_WRITE read/write type and for numerical data type. They specify if and how the RDS alarm is used. When the attribute is read, if the difference between its read value and the last written value is something more than or equal to the delta_val parameter and if at least delta_val milli seconds occurs since the last write operation, the attribute quality factor will be set to Tango::ATTR_ALARM and if the device state is Tango::ON, it is switched to Tango::ALARM. Even if these parameters are numbers, they are returned as strings by the device get_attribute_config() call.

#### The event related configuration parameters

Six event related attribute parameters are modifiable at run-time via a device call or via the property database.

Parameter name | Parameter description
--- | ---
rel_change | Relative change triggering change event
abs_change | Absolute change triggering change event
period | Period for periodic event
archive_rel_change | Relative change for archive event
archive_abs_change | Absolute change for archive event
archive_period | Period for change archive event

##### The rel_change and abs_change parameters

Rel_change is a property with a maximum of 2 values (comma separated). It specifies the increasing and decreasing relative change of the attribute value (w.r.t. the value of the previous change event) which will trigger the event. If the attribute is a spectrum or an image then a change event is generated if any one of the attribute value’s satisfies the above criterium. It’s the absolute value of these values which is taken into account. If only one value is specified then it is used for the increasing and decreasing change.

Abs_change is a property of maximum 2 values (comma separated). It specifies the increasing and decreasing absolute change of the attribute value (w.r.t the value of the previous change event) which will trigger the event. If the attribute is a spectrum or an image then a change event is generated if any one of the attribute value’s satisfies the above criterium. If only one value is specified then it is used for the increasing and decreasing change. If no values are specified then the relative change is used.

##### The periodic period parameter

The minimum time between events (in milliseconds). If no property is specified then a default value of 1 second is used.

##### The archive_rel_change, archive_abs_change and archive_period parameters

archive_rel_change is an array property of maximum 2 values which specifies the positive and negative relative change w.r.t. the previous attribute value which will trigger the event. If the attribute is a spectrum or an image then an archive event is generated if any one of the attribute value’s satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no properties are specified then a default fo +-10% is used

archive_abs_change is an array property of maximum 2 values which specifies the positive and negative absolute change w.r.t the previous attribute value which will trigger the event. If the attribute is a spectrum or an image then an archive event is generated if any one of the attribute value’s satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no properties are specified then the relative change is used.

archive_period is the minimum time between archive events (in milliseconds). If no property is specified, no periodic archiving events are send.

### Setting modifiable attribute parameters

A default value is given to all modifiable attribute parameters by the Tango core classes. Nevertheless, it is possible to modify these values in source code at attribute creation time or via the database. Values retrieved from the database have a higher priority than values given at attribute creation time. The attribute parameters are therefore initialized from:

1. The Database

2. If nothing in database, from the Tango class default

3. If nothing in database nor in Tango class default, from the library default value

The default value set by the Tango core library are

Parameter type | Parameter name | Library default value
--- | --- | ---
general purpose | description | No description
label | attribute name
unit | One empty string
standard_unit | No standard unit
display_unit | No display unit
format | 6 characters with 2 decimal
min_value | Not specified
max_value | Not specified
alarm parameters | min_alarm | Not specified
max_alarm | Not specified
min_warning | Not specified
max_warning | Not specified
& delta_t | Not specified
delta_val | Not specified
event parameters | rel_change | Not specified
abs_change | Not specified
period | 1000 (mS)
archive_rel_change | Not specified
archive_abs_change | Not specified
archive_period | Not specified

It is possible to set modifiable parameters via the database at two levels :

1. At class level

2. At device level. Each device attribute have all its modifiable parameters sets to the value defined at class level. If the setting defined at class level is not correct for one device, it is possible to re-define it.

If we take the example of a class called BumperPowerSupply with three devices called sr/bump/1, sr/bump/2 and sr/bump/3 and one attribute called wanted_current. For the first two bumpers, the max_value is equal to 500. For the third one, the max_value is only 400. If the max_value parameter is defined at class level with the value 500, all devices will have 500 as max_value for the wanted_current attribute. It is necessary to re-defined this parameter at device level in order to have the max_value for device sr/bump/3 set to 400.

For the description, label, unit, standard_unit, display_unit and format parameters, it is possible to return them to their default value by setting them to an empty string.

### Resetting modifiable attribute parameters

It is possible to reset attribute parameters to their default value at any moment. This could be done via the network call available through the DeviceProxy::set_attribute_config() method family. This call takes attribute parameters as strings. The following table describes which string has to be used to reset attribute parameters to their default value. In this table, the user default are the values given within Pogo in the Properties tab of the attribute edition window (or in in Tango class code using the Tango::UserDefaultAttrProp class).

Input string | Action
--- | ---
‘Not specified’ | Reset to library default
‘’(empty string) | Reset to user default if any. Otherwise, reset to library default
‘NaN’ | Reset to Tango class default if any. Otherwise, reset to user default (if any) or to library default

Let’s take one exemple: For one attribute belonging to a device, we have the following attribute parameters:

Parameter name

> Def. class

> Def. user

> Def. lib

standard_unit

> No standard unit

min_value

> 5

> Not specified

max_value

> 50

> Not specified

rel_change

> 5

> 10

> Not specified

The string Not specified sent to each attribute parameter will set attribute parameter value to No standard unit for standard_unit, Not specified for min_value, Not specified for max_value and Not specified as well for rel_change. The empty string sent to each attribute parameter will result with No stanadard unit for standard_unit, 5 for min_value, Not specified for max_value and 10 for rel_change. The string NaN will give No standard unit for standard_unit, 5 for min_value, 50 for max_value and 5 for rel_change.

C++ specific: Instead of the string Not specified and NaN, the preprocessor define AlrmValueNotSpec and NotANumber can be used.

## Device pipe

Pipe are configured with two kind of parameters: Parameters hard-coded in source code and modifiable parameters

### Hard-coded device pipe parameters

Three pipe parameters are defined at pipe creation time in the Tango class source code. Obviously, these parameters are not modifiable except with a new source code compilation. These parameters are

Parameter name | Parameter description
--- | ---
name | Pipe name
writable | Pipe read/write type
disp_level | Pipe display level

#### The pipe read/write type.

Tango supports two kinds of read/write pipe which are :

- Tango::PIPE_READ for read only pipe

- Tango::PIPE_READ_WRITE for pipe which can be read and written

#### The pipe display level parameter

This parameter is only an help for graphical application. It is a C++ enumeration starting at 0. The code associated with each pipe display level is defined in the following table (Tango::DispLevel).

name | Value
--- | ---
Tango::OPERATOR | 0
Tango::EXPERT | 1

This parameter allows a graphical application to support two types of operation :

- An operator mode for day to day operation

- An expert mode when tuning is necessary

According to this parameter, a graphical application knows if the pipe is for the operator mode or for the expert mode.

### Modifiable pipe parameters

Each pipe has a configuration set of 2 modifiable parameters. These parameters are modifiable at run-time via a device call or via the property database.

Parameter name | Parameter description
--- | ---
description | Pipe description
label | Pipe label

The description parameter describes the pipe. The label parameter is used by graphical application to display a label when this pipe is used in a graphical application.

### Setting modifiable pipe parameters

A default value is given to all modifiable pipe parameters by the Tango core classes. Nevertheless, it is possible to modify these values in source code at pipe creation time or via the database. Values retrieved from the database have a higher priority than values given at pipe creation time. The pipe parameters are therefore initialized from:

1. The Database

2. If nothing in database, from the Tango class default

3. If nothing in database nor in Tango class default, from the library default value

The default value set by the Tango core library are

Parameter name | Library default value
--- | ---
description | No description
label | pipe name

It is possible to set modifiable parameters via the database at two levels :

1. At class level

2. At device level. Each device pipe have all its modifiable parameters sets to the value defined at class level. If the setting defined at class level is not correct for one device, it is possible to re-define it.

This is the same principle than the one used for attribute configuration modifiable parameters.

### Resetting modifiable pipe parameters

It is possible to reset pipe parameters to their default value at any moment. This could be done via the network call available through the DeviceProxy::set_pipe_config() method family. It uses the same principle than the one used for resetting modifiable attribute pipe parameters. Refer to their documentation if you want to know details about this feature.

## Device class parameter

A device documentation field is also defined at Tango device class level. It is defined as Tango device class level because each device belonging to a Tango device class should have the same behaviour and therefore the same documentation. This field is store in the DeviceClass class. It is possible to set this field via a class property. This property name is

class name->doc_url

and is retrieved when instance of the DeviceClass object is created. A default value is defined for this field.

## The device black box

This black box is a help tool to ease debugging session for a running device server. The TANGO core software records every device request in this black box. A tango client is able to retrieve the black box contents with a specific CORBA operation availabble for every device. Each black box entry is returned as a string with the following information :

- The date where the request has been executed by the device. The date format is dd/mm/yyyy hh24:mi:ss:SS (The last field is the second hundredth number).

- The type of CORBA requests. In case of attributes, the name of the requested attribute is returned. In case of operation, the operation type is returned. For “command_inout” operation, the command name is returned.

- The client host name

## Automatically added commands

As already mentionned in this documentation, each Tango device supports at least three commands which are State, Status and Init. The following array details command input and output data type

Command name | Input data type | Output data type
--- | --- | ---
State | void | Tango::DevState
Status | void | Tango::DevString
Init | void | void

### The State command

This command gets the device state (stored in its device_state data member) and returns it to the caller. The device state is a variable of the Tango_DevState type (packed into a CORBA Any object when it is returned by a command)

### The Status command

This command gets the device status (stored in its device_status data member) and returns it to the caller. The device status is a variable of the string type.

### The Init command

This commands re-initialise a device keeping the same network connection. After an Init command executed on a device, it is not necessary for client to re-connect to the device. This command first calls the device delete_device() method and then execute its init_device() method. For C++ device server, all the memory allocated in the init_device() method must be freed in the delete_device() method. The language device desctructor automatically calls the delete_device() method.

## DServer class device commands

As already explained in [DServer_class], each device server process has its own Tango device. This device supports the three commands previously described plus 32 commands which are DevRestart, RestartServer, QueryClass, QueryDevice, Kill, QueryWizardClassProperty, QueryWizardDevProperty, QuerySubDevice, the polling related commands which are StartPolling, StopPolling, AddObjPolling, RemObjPolling, UpdObjPollingPeriod, PolledDevice and DevPollStatus, the device locking related commands which are LockDevice, UnLockDevice, ReLockDevices and DevLockStatus, the event related commands called EventSubscriptionChange, ZmqEventSubscriptionChange and EventConfirmSubscription and finally the logging related commands which are AddLoggingTarget, RemoveLoggingTarget, GetLoggingTarget, GetLoggingLevel, SetLoggingLevel, StopLogging and StartLogging. The following table give all commands input and output data types

Command name | Input data type | Output data type
--- | --- | ---
State | void | Tango::DevState
Status | void | Tango::DevString
Init | void | void
DevRestart | Tango::DevString | void
RestartServer | void | void
QueryClass | void | Tango::DevVarStringArray
QueryDevice | void | Tango::DevVarStringArray
Kill | void | void
QueryWizardClassProperty | Tango::DevString | Tango::DevVarStringArray
QueryWizardDevProperty | Tango::DevString | Tango::DevVarStringArray
QuerySubDevice | void | Tango::DevVarStringArray
StartPolling | void | void
StopPolling | void | void
AddObjPolling | Tango::DevVarLongStringArray | void
RemObjPolling | Tango::DevVarStringArray | void
UpdObjPollingPeriod | Tango::DevVarLongStringArray | void
PolledDevice | void | Tango::DevVarStringArray
DevPollStatus | Tango::DevString | Tango::DevVarStringArray
LockDevice | Tango::DevVarLongStringArray | void
UnLockDevice | Tango::DevVarLongStringArray | Tango::DevLong
ReLockDevices | Tango::DevVarStringArray | void
DevLockStatus | Tango::DevString | Tango::DevVarLongStringArray
EventSubscribeChange | Tango::DevVarStringArray | Tango::DevLong
ZmqEventSubscriptionChange | Tango::DevVarStringArray | Tango::DevVarLongStringArray
EventConfirmSubscription | Tango::DevVarStringArray | void
AddLoggingTarget | Tango::DevVarStringArray | void
RemoveLoggingTarget | Tango::DevVarStringArray | void
GetLoggingTarget | Tango::DevString | Tango::DevVarStringArray
GetLoggingLevel | Tango::DevVarStringArray | Tango::DevVarLongStringArray
SetLoggingLevel | Tango::DevVarLongStringArray | void
StopLogging | void | void
StartLogging | void | void

The device description field is set to “A device server device”. Device server started with the -file command line option also supports a command called QueryEventChannelIOR. This command is used interanally by the Tango kernel classes when the event system is used with device server using database on file.

### The State command

This device state is always set to ON

### The Status command

This device status is always set to “The device is ON” followed by a new line character and a string describing polling thread status. This string is either “The polling is OFF” or “The polling is ON” according to polling state.

### The DevRestart command

The DevRestart command restart a device. The name of the device to be re-started is the command input parameter. The command destroys the device by calling its destructor and re-create it from its constructor.

### The RestartServer command

The DevRestartServer command restarts all the device pattern(s) embedded in the device server process. Therefore, all the devices implemented in the server process are destroyed and re-built [1]. The network connection between client(s) and device(s) implemented in the device server process is destroyed and re-built.

Executing this command allows a complete restart of the device server without stopping the process.

### The QueryClass command

This command returns to the client the list of Tango device class(es) embedded in the device server. It returns only class(es) implemented by the device server programmer. The DServer device class name (implemented by the TANGO core software) is not returned by this command.

### The QueryDevice command

This command returns to the client the list of device name for all the device(s) implemented in the device server process. Each device name is returned using the following syntax :

<class name>::<device name>

The name of the DServer class device is not returned by this command.

### The Kill command

This command stops the device server process. In order that the client receives a last answer from the server, this command starts a thread which will after a short delay, kills the device server process.

### The QueryWizardClassProperty command

This command returns the list of property(ies) defined for a class stored in the device server process property wizard. For each property, its name, a description and a default value is returned.

### The QueryWizardDevProperty command

This command returns the list of property(ies) defined for a device stored in the device server process property wizard. For each property, its name, a description and a default value is returned.

### The QuerySubDevice command

This command returns the list of sub-device(s) imported by each device within the server. A sub-device is a device used ( to execute command(s) and/or to read/write attribute(s) ) by one of the device server process devices. There is one element in the returned strings array for each sub-device. The syntax of each string is the device name, a space and the sub-device name. In case of device server process starting threads using a sub-device, it is not possible to link this sub-device to any process devices. In such a case, the string contains only the sub-device name

### The StartPolling command

This command starts the polling thread

### The StopPolling command

This command stops the polling thread

### The AddObjPolling command

This command adds a new object in the list of object(s) to be polled. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and three strings. The input parameters are:

Command parameter | Parameter meaning
--- | ---
svalue[0] | Device name
svalue[1] | Object type (“command“ or “attribute“)
svalue[2] | Object name
lvalue[0] | polling period in mS

The object type string is case independent. The object name string (command name or attribute name) is case dependant. This command does not start polling if it is stopped. This command is not allowed in case the device is locked and the command requester is not the lock owner.

### The RemObjPolling command

This command removes an object of the list of polled objects. The command input data type is a Tango::DevVarStringArray with three strings. These strings meaning are :

String | Meaning
--- | ---
string[0] | Device name
string[1] | Object type (“command“ or “attribute“)
string[2] | Object name

The object type string is case independent. The object name string (command name or attribute name) is case dependant. This command is not allowed in case the device is locked and the command requester is not the lock owner.

### The UpdObjPollingPeriod command

This command changes the polling period for a specified object. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and three strings. The input parameters are:

Command parameter | Parameter meaning
--- | ---
svalue[0] | Device name
svalue[1] | Object type (“command“ or “attribute“)
svalue[2] | Object name
lvalue[0] | new polling period in mS

The object type string is case independent. The object name string (command name or attribute name) is case dependant. This command does not start polling if it is stopped. This command is not allowed in case the device is locked and the command requester is not the lock owner.

### The PolledDevice command

This command returns the name of device which are polled. Each string in the Tango::DevVarStringArray returned by the command is a device name which has at least one command or attribute polled. The list is alphabetically sorted.

### The DevPollStatus command

This command returns a polling status for a specific device. The input parameter is a device name. Each string in the Tango::DevVarStringArray returned by the command is the polling status for each polled device objects (command or attribute). For each polled objects, the polling status is :

- The object name

- The object polling period (in mS)

- The object polling ring buffer depth

- The time needed (in mS) for the last command execution or attribute reading

- The time since data in the ring buffer has not been updated. This allows a check of the polling thread

- The delta time between the last records in the ring buffer. This allows checking that the polling period is respected by the polling thread.

- The exception parameters in case of the last command execution or the last attribute reading failed.

A new line character is inserted between each piece of information.

### The LockDevice command

This command locks a device for the calling process. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and one string. The input parameters are:

Command parameter | Parameter meaning
--- | ---
svalue[0] | Device name
lvalue[0] | Lock validity

### The UnLockDevice command

This command unlocks a device. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and one string. The input parameters are:

Command parameter | Parameter meaning
--- | ---
svalue[0] | Device name
lvalue[0] | Force flag

The force flag parameter allows a client to unlock a device already locked by another process (for admin usage only)

### The ReLockDevices command

This command re-lock devices. The input argument is the list of devices to be re-locked. It’s an error to re-lock a device which is not already locked.

### The DevLockStatus command

This command returns a device locking status to the caller. Its input parameter is the device name. The output parameters are embedded within a Tango::DevVarLongStringArray data type with three strings and six long. These data are

Command parameter | Parameter meaning
--- | ---
svalue[0] | Locking string
svalue[1] | CPP client host IP address or Not defined
svalue[2] | Java VM main class for Java client or Not defined
lvalue[0] | Lock flag (1 if locked, 0 othterwise)
lvalue[1] | CPP client host IP address or 0 for Java locker
lvalue[2] | Java locker UUID part 1or 0 for CPP locker
lvalue[3] | Java locker UUID part 2 or 0 for CPP locker
lvalue[4] | Java locker UUID part 3 or 0 for CPP locker
lvalue[5] | Java locker UUID part 4 or 0 for CPP locker

### The EventSubscriptionChange command (C++ server only)

This command is used as a piece of the heartbeat system between an event client and the device server generating the event. There is no reason to generate events if there is no client which has subscribed to it. It is used by the DeviceProxy::subscribe_event() method and one of the event thread on the client side to inform the server to keep on generating events for the attribute in question. It reloads the subscription timer with the current time. Events are not generated when there are no clients subscribed within the last 10 minutes. The input parameters are:

Command parameter | Parameter meaning
--- | ---
argin[0] | Device name
argin[1] | Attribute name
argin[2] | action (subscribe or unsubsribe)
argin[3] | event name (change, periodic, archive,attr_conf)

The command output data is the simply the Tango release used by the device server process. This is necessary for compatibility reason.

### The ZmqEventSubscriptionChange command

This command is used as a piece of the heartbeat system between an event client and the device server generating the event when client and/or device server uses Tango release 8 or above. There is no reason to generate events if there is no client which has subscribed to it. It is used by the DeviceProxy::subscribe_event() method and one of the event thread on the client side to inform the server to keep on generating events for the attribute in question. It reloads the subscription timer with the current time. Events are not generated when there are no clients subscribed within the last 10 minutes. The input parameters are the same than the one used for the EventSubscriptionChange command. They are:

Command in parameter | Parameter meaning
--- | ---
argin[0] | Device name
argin[1] | Attribute/pipe name
argin[2] | action (subscribe or unsubsribe)
argin[3] | event name (change, quality, periodic, archive, user_event, attr_conf, data_ready, intr_change, pipe)
argin[4] | <Tango client IDL version>

The command output parameters aer all the necessary data to build one event connection between a client and the device server process generating the events. This means:

Command out parameter | Parameter meaning
--- | ---
svalue[0] | Heartbeat ZMQ socket connect end point
svalue[1] | Event ZMQ socket connect end point
svalue[2] | <Alternate Heartbeat pub endpoint>
svalue[3] | <Alternate Event pub endpoint>
… |
svalue[n-3] | <Alternate Heartbeat pub endpoint>
svalue[n-2] | <Alternate Event pub endpoint>
svalue[n-1] | event name used by this server as zmq topic to send events
svalue[n] | channel name used by this server to send heartbeat events
lvalue[0] | Tango lib release used by device server
lvalue[1] | Device IDL release
lvalue[2] | Subscriber HWM
lvalue[3] | Rate (Multicasting related)
lvalue[4] | IVL (Multicasting related)
lvalue[5] | ZMQ release

### The EventConfirmSubscription command

This command is used by client to regularly notify to device server process their interest in receiving events. If this command is not received, after a delay of 600 sec (10 mins), event(s) will not be sent any more. The input parameters for the EventConfirmSubscription command must be a multiple of 3. They are 3 parameters for each event confirmed by this command. Per event, these parameters are:

Command in parameter | Parameter meaning
--- | ---
argin[x] | Device name
argin[x + 1] | Attribute name
argin[x + 2] | Event name

### The AddLoggingTarget command

This command adds one (or more) logging target(s) to the specified device(s). The command input parameter is an array of string logically composed of {device_name, target_type::target_name} groups where the elements have the following semantic:

- device_name is the name of the device which logging behavior is to be controlled. The wildcard is supported to apply the modification to all devices encapsulated within the device server (e.g. to ask all devices to log to the same device target).

- target_type::target_name: target_type is one of the supported target types and target_name, the name of the target. Supported target types are: console, file and device. For a device target, target_name must contain the name of a log consumer device (as defined in [sec:Tango-log-consumer]). For a file target, target_name is the full path to the file to log to. If omitted the device’s name is used to build the file name (domain_family_member.log). Finally, target_name is ignored in the case of a console target and can be omitted.

This command is not allowed in case the device is locked and the command requester is not the lock owner.

### The RemoveLoggingTarget command

Remove one (or more) logging target(s) from the specified device(s).The command input parameter is an array of string logically composed of {device_name, target_type::target_name} groups where the elements have the following semantic:

- device_name: the name of the device which logging behavior is to be controlled. The wildcard is supported to apply the modification to all devices encapsulated within the device server (e.g. to ask all devices to stop logging to a given device target).

- target_type::target_name: target_type is one of the supported target types and target_name, the name of the target. Supported target types are: console, file and device. For a device target, target_name must contain the name of a log consumer device (as defined in [sec:Tango-log-consumer]). For a file target, target_name is the full path to the file to log to. If omitted the device’s name is used to build the file name (domain_family_member.log). Finally, target_name is ignored in the case of a console target and can be omitted.

The wildcard is supported for target_name. For instance, RemoveLoggingTarget ([, device::*) removes all the device targets from all the devices running in the device server. This command is not allowed in case the device is locked and the command requester is not the lock owner.

### The GetLoggingTarget command

Returns the current target list of the specified device. The command parameter device_name is the name of the device which logging target list is requested. The list is returned as a DevVarStringArray containing target_type::target_name elements.

### The GetLoggingLevel command

Returns the logging level of the specified devices. The command input parameter device_list contains the names of the devices which logging target list is requested. The wildcard is supported to get the logging level of all the devices running within the server. The string part of the result contains the name of the devices and its long part contains the levels. Obviously, result.lvalue[i] is the current logging level of the device named result.svalue[i].

### The SetLoggingLevel command

Changes the logging level of the specified devices. The string part of the command input parameter contains the device names while its long part contains the logging levels. The set of possible values for levels is: 0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG.

The wildcard is supported to assign all devices the same logging level. For instance, SetLoggingLevel ([3]) set the logging level of all the devices running within the server to WARNING. This command is not allowed in case the device is locked and the command requester is not the lock owner.

### The StopLogging command

For all the devices running within the server, StopLogging saves their current logging level and set their logging level to OFF.

### The StartLogging command

For each device running within the server, StartLogging restores their logging level to the value stored during a previous StopLogging call.

## DServer class device properties

This device has two properties related to polling threads pool management plus another one for the choice of polling algorithm. These properties are described in the following table

Property name | property rule | default value
--- | --- | ---
polling_threads_pool_size | Max number of thread in the polling pool | 1
polling_threads_pool_conf | Polling threads pool configuration |
polling_before_9 | Choice of the polling algorithm | false

The rule of the polling_threads_pool_size is to define the maximun number of thread created for the polling threads pool size. The rule of the polling_threads_pool_conf is to define which thread in the pool is in charge of all the polled object(s) of which device. This property is an array of strings with one string per used thread in the pool. The content of the string is simply a device name list with device name splitted by a comma. Example of polling_threads_pool_conf property for 3 threads used:

    1  dserver/<ds exec name>/<inst. name>/polling_threads_pool_conf-> the/dev/01
    2                    the/dev/02,the/dev/06
    3                    the/dev/03

Thread number 2 is in charge of 2 devices. Note that there is an entry in this list only for the used threads in the pool.

The rule of the polling_before_9 property is to select the polling algorithm which was used in Tango device server process before Tango release 9.

## Tango log consumer

### The available Log Consumer

One implementation of a log consumer associated to a graphical user interface is available within Tango. It is a standalone java application called LogViewer based on the publicly available chainsaw application from the log4j package. It supports two way of running which are:

- The static mode: In this mode, LogViewer is started with a parameter which is the name of the log consumer device implemented by the application. All messages sent by devices with a logging target type set to device and with a logging target name set to the same device name than the device name passed as application parameter will be displayed (if the logging level allows it).

- The dynamic mode: In this mode, the name of the log consumer device implemented by the application is build at application startup and is dynamic. The user with the help of the graphical interface chooses device(s) for which he want to see log messages.

### The Log Consumer interface

A Tango Log Consumer device is nothing but a tango device supporting the following tango command :

void log (Tango::DevVarStringArray details)

where details is an array of string carrying the log details. Its structure is:

- details[0] : the timestamp in millisecond since epoch (01.01.1970)

- details[1] : the log level

- details[2] : the log source (i.e. device name)

- details[3] : the log message

- details[4] : the log NDC (contextual info) - Not used but reserved

- details[5] : the thread identifier (i.e. the thread from which the log request comes from)

These log details can easily be extended. Any tango device supporting this command can act as a device target for other devices.

## Control system specific

It is possible to define a few control system parameters. By control system, we mean for each set of computers having the same database device server (the same TANGO_HOST environment variable)

### The device class documentation default value

Each control system may have it’s own default device class documentation value. This is defined via a class property. The property name is

Default->doc_url

It’s retrieved if the device class itself does not define any doc_url property. If the Default->doc_url property is also not defined, a hard-coded default value is provided.

### The services definition

The property used to defined control system services is named Services and belongs to the free object CtrlSystem. This property is an array of strings. Each string defines a service available within the control system. The syntax of each service definition is

Service name/Instance name:service device name

### Tuning the event system buffers (HWM)

Starting with Tango release 8, ZMQ is used for the event based communication between clients and device server processes. ZMQ implementation provides asynchronous communication in the sense that the data to be transmitted is first stored in a buffer and then really sent on the network by dedicated threads. The size of this buffers (on client and device server side) is called High Water Mark (HWM) and is tunable. This is tunable at several level.

1. The library set a default value of 1000 for both buffers (client and device server side)

2. Control system properties used to tune these size are named DSEventBufferHwm (device server side) and EventBufferHwm (client side). They both belongs to the free object CtrlSystem. Each property is the max number of events storable in these buffer.

3. At client or device server level using the library calls Util::set_ds_event_buffer_hwm() documented in [TangoRefMan] or ApiUtil::set_event_buffer_hwm() documented in `Tango::ApiUtil`

4. Using environment variables TANGO_DS_EVENT_BUFFER_HWM or TANGO_EVENT_BUFFER_HWM

### Allowing NaN when writing attributes (floating point)

A property named WAttrNaNAllowed belonging to the free object CtrlSystem allows a Tango control system administrator to allow or disallow NaN numbers when writing attributes of the DevFloat or DevDouble data type. This is a boolean property and by default, it’s value is taken as false (Meaning NaN values are rejected).

### Tuning multicasting event propagation

Starting with Tango 8.1, it is possible to transfer event(s) between devices and clients using a multicast protocol. The properties MulticastEvent, MulticastRate, MulticastIvl and MulticastHops also belonging to the free object CtrlSystem allow the user to configure which events has to be sent using multicasting and with which parameters. See chapter Advanced features/Using multicast protocol to transfer events to get details about these properties.

### Summary of CtrlSystem free object properties

The following table summarizes properties defined at control system level and belonging to the free object CtrlSystem

Property name | property rule | default value
--- | --- | ---
Services | List of defined services | No default
DsEventBufferHwm | DS event buffer high water mark | 1000
EventBufferHwm | Client event buffer high water mark | 1000
WAttrNaNAllowed | Allow NaN when writing attr. | false
MulticastEvent | List of multicasting events | No default
MulticastRate | Rate for multicast event transport | 80
MulticastIvl | Time to keep data for re-transmission | 20
MulticastHops | Max number of elements to cross | 5

## C++ specific

### The Tango master include file (tango.h)

Tango has a master include file called

tango.h

This master include file includes the following files :

- Tango configuration include file : tango_config.h

- CORBA include file : idl/tango.h

- Some network include files for WIN32 : winsock2.h and mswsock.h

- C++ streams include file :

  - iostream, sstream and fstream

- Some standard C++ library include files : memory, string and vector

- A long list of other Tango include files

### Tango specific pre-processor define

The tango.h previously described also defined some pre-processor macros allowing Tango release to be checked at compile time. These macros are:

- TANGO_VERSION_MAJOR

- TANGO_VERSION_MINOR

- TANGO_VERSION_PATCH

For instance, with Tango release 8.1.2, TANGO_VERSION_MAJOR will be set to 8 while TANGO_VERSION_MINOR will be 1 and TANGO_VERSION_PATCH will be 2.

### Tango specific types

#### Operating system free type

Some data type used in the TANGO core software have been defined. They are described in the following table.

Type name | C++ name
--- | ---
TangoSys_MemStream | stringstream
TangoSys_OMemStream | ostringstream
TangoSys_Pid | int
TangoSys_Cout | ostream

These types are defined in the tango_config.h file

#### Template command model related type

As explained in [Command fact], command created with the template command model uses static casting. Many type definition have been written for these casting.

Class name | Command allowed method (if any) | Command execute method
--- | --- | ---
TemplCommand | Tango::StateMethodPtr | Tango::CmdMethPtr
TemplCommandIn | Tango::StateMethodPtr | Tango::CmdMethPtr_xxx
TemplCommandOut | Tango::StateMethodPtr | Tango::xxx_CmdMethPtr
TemplCommandInOut | Tango::StateMethodPtr | Tango::xxx_CmdMethPtr_yyy

The Tango::StateMethPtr is a pointer to a method of the DeviceImpl class which returns a boolean and has one parameter which is a reference to a const CORBA::Any obect.

The Tango::CmdMethPtr is a pointer to a method of the DeviceImpl class which returns nothing and needs nothing as parameter.

The Tango::CmdMethPtr_xxx is a pointer to a method of the DeviceImpl class which returns nothing and has one parameter. xxx must be set according to the method parameter type as described in the next table

Tango type | short cut (xxx)
--- | ---
Tango::DevBoolean | Bo
Tango::DevShort | Sh
Tango::DevLong | Lg
Tango::DevFloat | Fl
Tango::DevDouble | Db
Tango::DevUshort | US
Tango::DevULong | UL
Tango::DevString | Str
Tango::DevVarCharArray | ChA
Tango::DevVarShortArray | ShA
Tango::DevVarLongArray | LgA
Tango::DevVarFloatArray | FlA
Tango::DevVarDoubleArray | DbA
Tango::DevVarUShortArray | USA
Tango::DevVarULongArray | ULA
Tango::DevVarStringArray | StrA
Tango::DevVarLongStringArray | LSA
Tango::DevVarDoubleStringArray | DSA
Tango::DevState | Sta

For instance, a pointer to a method which takes a Tango::DevVarStringArray as input parameter must be statically casted to a Tango::CmdMethPtr_StrA, a pointer to a method which takes a Tango::DevLong data as input parameter must be statically casted to a Tango::CmdMethPtr_Lg.

The Tango::xxx_CmdMethPtr is a pointer to a method of the DeviceImpl class which returns data of one of the Tango type and has no input parameter. xxx must be set according to the method return data type following the same rules than those described in the previous table. For instance, a pointer to a method which returns a Tango::DevDouble data must be statically casted to a Tango::Db_CmdMethPtr.

The Tango::xxx_CmdMethPtr_yyy is a pointer to a method of the DeviceImpl class which returns data of one of the Tango type and has one input parameter of one of the Tango data type. xxx and yyy must be set according to the method return data type and parameter type following the same rules than those described in the previous table. For instance, a pointer to a method which returns a Tango::DevDouble data and which takes a Tango::DevVarLongStringArray must be statically casted to a Tango::Db_CmdMethPtr_LSA.

All those type are defined in the tango_const.h file.

### Tango device state code

The Tango::DevState type is a C++ enumeration starting at 0. The code associated with each state is defined in the following table.

State name | Value
--- | ---
Tango::ON | 0
Tango::OFF | 1
Tango::CLOSE | 2
Tango::OPEN | 3
Tango::INSERT | 4
Tango::EXTRACT | 5
Tango::MOVING | 6
Tango::STANDBY | 7
Tango::FAULT | 8
Tango::INIT | 9
Tango::RUNNING | 10
Tango::ALARM | 11
Tango::DISABLE | 12
Tango::UNKNOWN | 13

A strings array called Tango::DevStateName can be used to get the device state as a string. Use the Tango device state code as index into the array to get the correct string.

### Tango data type

A “define” has been created for each Tango data type. This is summarized in the following table

Type name | Type code | Value
--- | --- | ---
Tango::DevBoolean | Tango::DEV_BOOLEAN | 1
Tango::DevShort | Tango::DEV_SHORT | 2
Tango::DevLong | Tango::DEV_LONG | 3
Tango::DevFloat | Tango::DEV_FLOAT | 4
Tango::DevDouble | Tango::DEV_DOUBLE | 5
Tango::DevUShort | Tango::DEV_USHORT | 6
Tango::DevULong | Tango::DEV_ULONG | 7
Tango::DevString | Tango::DEV_STRING | 8
Tango::DevVarCharArray | Tango::DEVVAR_CHARARRAY | 9
Tango::DevVarShortArray | Tango::DEVVAR_SHORTARRAY | 10
Tango::DevVarLongArray | Tango::DEVVAR_LONGARRAY | 11
Tango::DevVarFloatArray | Tango::DEVVAR_FLOATARRAY | 12
Tango::DevVarDoubleArray | Tango::DEVVAR_DOUBLEARRAY | 13
Tango::DevVarUShortArray | Tango::DEVVAR_USHORTARRAY | 14
Tango::DevVarULongArray | Tango::DEVVAR_ULONGARRAY | 15
Tango::DevVarStringArray | Tango::DEVVAR_STRINGARRAY | 16
Tango::DevVarLongStringArray | Tango::DEVVAR_LONGSTRINGARRAY | 17
Tango::DevVarDoubleStringArray | Tango::DEVVAR_DOUBLESTRINGARRAY | 18
Tango::DevState | Tango::DEV_STATE | 19
Tango::ConstDevString | Tango::CONST_DEV_STRING | 20
Tango::DevVarBooleanArray | Tango::DEVVAR_BOOLEANARRAY | 21
Tango::DevUChar | Tango::DEV_UCHAR | 22
Tango::DevLong64 | Tango::DEV_LONG64 | 23
Tango::DevULong64 | Tango::DEV_ULONG64 | 24
Tango::DevVarLong64Array | Tango::DEVVAR_LONG64ARRAY | 25
Tango::DevVarULong64Array | Tango::DEVVAR_ULONG64ARRAY | 26
Tango::DevInt | Tango::DEV_INT | 27
Tango::DevEncoded | Tango::DEV_ENCODED | 28
Tango::DevEnum | Tango::DEV_ENUM | 29
Tango::DevPipeBlob | Tango::DEV_PIPE_BLOB | 30
Tango::DevVarStateArray | Tango::DEVVAR_STATEARRAY | 31

For command which do not take input parameter, the type code Tango::DEV_VOID (value = 0) has been defined.

Use Tango::data_type_to_string to convert the tango data type to a string. For older tango versions without that function a strings array called Tango::CmdArgTypeName can be used to get the data type as a string. Use the Tango data type code as index into the array to get the correct string.

### Tango command display level

Like attribute, Tango command has a display level. The Tango::DispLevel type is a C++ enumeration starting at 0. The code associated with each command display level is already described in page

As for attribute, this parameter allows a graphical application to support two types of operation :

- An operator mode for day to day operation

- An expert mode when tuning is necessary

According to this parameter, a graphical application knows if the command is for the operator mode or for the expert mode.

## Device server process option and environment variables

### Classical device server

The synopsis of a device server process is

ds_name instance_name [OPTIONS]

The supported options are :

- -h, -? -help
  Print the device server synopsis and a list of instance name defined in the database for this device server. An instance name in not mandatory in the command line to use this option
- -v[trace level]
  Set the verbose level. If no trace level is given, a default value of 4 is used
- -file=<file name path>
  Start a device server using an ASCII file instead of the Tango database.
- -nodb
  Start a device server without using the database.
- -dlist <device name list>
  Give the device name list. This option is supported only with the -nodb option.
- ORB options (started with -ORBxxx)
  Options directly passed to the underlying ORB. Should be rarely used except the -ORBendPoint option for device server not using the database

### Device server process as Windows service

When used as a Windows service, a Tango device server supports several new options. These options are :

- -i
  Install the service
- -s
  Install the service and choose the automatic startup mode
- -u
  Un-install the service
- -dbg
  Run in console mode to debug service. The service must have been installed prior to use it.

Note that these options must be used after the device server instance name.

### Environment variables

A few environment variables can be used to tune a Tango control system. TANGO_HOST is the most important one but on top it, some Tango features like Tango logging service or controlled access (if used) can be tuned using environment variable. If these environment variables are not defined, the software searches in the file $HOME/.tangorc for its value. If the file is not defined or if the environment variable is also not defined in this file, the software searches in the file /etc/tangorc for its value. For Windows, the file is $TANGO_ROOT/tangorc TANGO_ROOT being the mandatory environment variable of the Windows binary distribution.

#### TANGO_HOST

This environment variable is the anchor of the system. It specifies where the Tango database server is running. Most of the time, its syntax is

TANGO_HOST=<host>:<port>

host is the name of the computer where the database server is running and port is the port number on which it is listening. <host> should be a FQDN (Fully Qualified Domain Name). If you want to have a Tango control system which has several database servers (but only one database) in order to survive a database server crash, use the following syntax

TANGO_HOST=<host_1>:<port_1>,<host_2>:<port_2>,<host_3>:<port_3>

Obviously, host_1 is the name of the computer where the first database server is running, port_1 is the port number on which this server is listening. host_2 is the name of the computer where the second database server is running and port_2 is its port number. All access to database will automatically switch from one server to another one in the list if the one which was used has died.

#### Tango Logging Service (TANGO_LOG_PATH)

The TANGO_LOG_PATH environment variable can be used to specify the log files location. If not set it defaults to /tmp/tango-<user logging name> under Unix and C:/tango-<user logging name> under Windows. For a given device-server, the files are actually saved into $TANGO_LOG_PATH/{ server_name}/{ server_instance_name}. This means that all the devices running within the same process log into the same directory.

#### The database and controlled access server (MYSQL_USER, MYSQL_PASSWORD, MYSQL_HOST and MYSQL_DATABASE)

The Tango database server and the controlled access server (if used) need to connect to the MySQL database. They are using four environment variables called MYSQL_USER, MYSQL_PASSWORD to know which user/password they must use to access the database, MYSQL_HOST in case the MySQL database is running on another host and MYSQL_DATABASE to specify the name of the database to connect to. The MYSQL_HOST environment variable allows you to specify the host and port number where MySQL is running. Its syntax is

host:port

The port definition is optional. If it is not specified, the default MySQL port will be used. If these environment variables are not defined, they will connect to the DBMS using the root login on localhost with the MySQL default port number (3306). The MYSQL_DATABASE environment variable has to be used in case your are using the same Tango Database device server executable code to connect to several Tango databases each of them having a different name.

#### The controlled access

Even if a controlled access system is running, it is possible to by-pass it if in the environment of the client application the environment variable SUPER_TANGO is defined to true.

#### The event buffer size

If required, the event buffer used by the ZMQ software could be tuned using environment variables. These variables are named TANGO_DS_EVENT_BUFFER_HWM for the event buffer on a device server side and TANGO_EVENT_BUFFER_HWM for the event buffer on the client size. Both of them are a number which is the maximum number of events which could be stored in these buffers.

[1]

Their black-box is also destroyed and re-built