---
domain: rfc.tango-controls.org
shortname: 4/Attribute
name: Attribute
status: stable
editor: Sergi Rubio (srubio@cells.es)
---

# 4/Attribute

This document describes the Tango Attribute model specification in Tango V9.

## Preamble

Copyright (c) 2019 Tango Controls Community.

This Specification 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. This Specification 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 this program; if not, see <http://www.gnu.org/licenses>.

This Specification is a [free and open standard](https://web.archive.org/web/20161002091934/http://www.digistan.org/open-standard:definition) and is governed by the Digital Standards Organization's [Consensus-Oriented Specification System](https://web.archive.org/web/20161002092144/http://www.digistan.org/spec:1/coss).

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC-2119](https://tools.ietf.org/html/rfc2119).


## Tango Attribute specification

This specification is intended to formally document the Tango Attribute static
model. Runtime representations of Attribute in conforming Tango implementations
MUST follow this specification.


### Goals

An Attribute is a Tango concept representing in the most cases a physical quantity of a device.
The main purpose of an Attribute is to provide read and (optionally) write
access to this quantity.

In object oriented terminology, the Attribute corresponds to an instance
variable (also called a field or a member) of a Device object.
See [2/Device](../2/Device.md) for the definition of the Device.

### Use Cases

Some example use cases of an Attribute are:
* an Attribute can represent the position of a motor device,
* an Attribute can represent the temperature reading of a thermocouple device.


## Specification

An Attribute has:
* A set of static metadata that constitute Attribute's definition,
* A set of dynamically configurable properties, e.g. alarm min and max values,
* A set of runtime parameters describing the Attribute's value.

### Attribute definition

The static metadata is part of the Attribute definition. It MUST be defined
before an Attribute is created by any Tango implementation and MUST NOT change
at runtime after the Attribute is initialized.

An Attribute MUST have the following static metadata associated:
* *name*, a string identifying the Attribute.
  It MUST be unique among all Attributes of a particular device.
  See `<attribute-name>` specification below,
* *data type*, an enumeration describing the type of the data ([9/DataTypes](../9/DataTypes.md)),
* *data format*, an enumeration describing the dimension of the data
  (one of *SCALAR*, *SPECTRUM*, *IMAGE*),
* *writable*, an enumeration describing the write access to the Attribute
  (one of *READ*, *WRITE*, *READ_WRITE*, *READ_WITH_WRITE*).
  * An Attribute can be read from, if *writable* is one of *READ*, *READ_WRITE*,
    *READ_WITH_WRITE*.
  * An Attribute can be written to, if *writable* is one of *WRITE*, *READ_WRITE*.
* *display level*, an enumeration describing visibility level of the Attribute
  (one of *EXPERT*, *OPERATOR*).

If *data format* is *SPECTRUM*,
an Attribute MUST have associated following additional static metadata:
* *max dim x*, an integer describing the maximum allowed number of data
  elements.
  * The Attribute MUST be able to store up to *max dim x* data elements.
  * It MUST be greater than 0.

If *data format* is *IMAGE*,
an Attribute MUST have associated following additional static metadata:
* *max dim x*, an integer describing the maximum allowed number of data
  elements in dimension X.
  * The Attribute MUST be able to store up to *max dim x* data elements
  in the X dimension.
  * It MUST be greater than 0,
* *max dim y*, an integer describing the maximum allowed number of data
  elements in dimension Y.
  * The Attribute MUST be able to store up to *max dim y* data elements
  in the Y dimension.
  * It MUST be greater than 0.

If *writable* is *READ_WITH_WRITE*,
an Attribute MUST have associated following additional static metadata:
* *writable attribute name*, a string describing the *name* of associated
  writable attribute.
  * It MUST point to an attribute.
  * The Attribute pointed to MUST have *writable* set to one of *WRITE*,
  *READ_WRITE*.

If *data type* is *ENUM*,
an Attribute MAY have associated following additional static metadata:
* *enum labels*, a list of strings describing textual representation
  of enumerated values.
  * It MAY be empty.


#### Memorized attribute

An Attribute MUST have associated following static metadata:
* *memorized*, a flag describing whether the *set value* is stored in the database
  and restored during Attribute initialization,
* *write hardware at init*, a flag describing whether the memorized
  *set value* is written to the Attribute during initialization or *init* call.
  **Note:** It is effective only if *memorized* is also set.

A conforming implementation MUST allow to set the *memorized* flag and MUST
support memorization for attributes which:
* *data format* is *SCALAR*,
* *writable* is *WRITE* or *READ_WRITE*,
* *data type* is not *STATE* or *ENCODED*.

If *memorized* is set and if database is being used,
the *set value* MUST be persisted in the *__value* Attribute property upon
each write to the Attribute.

If *memorized* is set and *__value* Attribute property is other than
"Not used yet" (default):
* only during Attribute initialization (at startup):
  * *set value* MUST be set with a value stored in *__value* Attribute property,
* during Attribute initialization (at startup) or during an *init* command
  execution, if *write hardware at init* is also set:
  * value stored in *set value* MUST be written to the Attribute.

#### Forwarded attribute

An Attribute can be a Forwarded Attribute. A Forwarded Attribute MUST have
associated a Root Attribute. This association is done with the *__root_att*
Attribute property on the Forwarded Attribute and:
- It MUST be defined before attribute initialization at startup.
- It MUST NOT be changed at runtime.
- It MUST point to an existing attribute in another device.

Allowed syntax for *__root_att* is specified below as `<full-attribute-name>`.

Each read and write request to a Forwarded Attribute MUST be passed
to the Root Attribute.

Each change to properties or to other metadata associated with a Forwarded
Attribute MUST be reflected in the Root Attribute.

Each change to properties or to other metadata associated with the Root Attribute
MUST be reflected in the Forwarded Attribute.


### Attribute properties

An Attribute MAY have associated dynamic metadata in form of
Properties (see [5/Property](../5/Property.md)).

The table below summarizes common attribute properties used by Tango.
A detailed description is provided later in this section.

| Property             | Name in database     | Type   | Default value                                                                                         |
|----------------------|----------------------|--------|-------------------------------------------------------------------------------------------------------|
| *description*        | `description`        | string | Not specified / No description                                                                        |
| *label*              | `label`              | string | Not specified / No label                                                                              |
| *unit*               | `unit`               | string | Not specified / No unit / *empty*                                                                     |
| *standard unit*      | `standard_unit`      | number | Not specified / No standard unit                                                                      |
| *display unit*       | `display_unit`       | number | Not specified / No display unit                                                                       |
| *format*             | `format`             | string | %6.2f (float),<br/> %d (integer),<br/> %s(string, enum),<br/> Not specified (state, encoded, boolean) |
| *min value*          | `min_value`          | number | Not specified                                                                                         |
| *max value*          | `max_value`          | number | Not specified                                                                                         |
| *min alarm*          | `min_alarm`          | number | Not specified                                                                                         |
| *max alarm*          | `max_alarm`          | number | Not specified                                                                                         |
| *min warning*        | `min_warning`        | number | Not specified                                                                                         |
| *max warning*        | `max_warning`        | number | Not specified                                                                                         |
| *delta val*          | `delta_val`          | number | Not specified                                                                                         |
| *delta t*            | `delta_t`            | number | Not specified / 0                                                                                     |
| *rel change*         | `rel_change`         | number | Not specified                                                                                         |
| *abs change*         | `abs_change`         | number | Not specified                                                                                         |
| *archive rel change* | `archive_rel_change` | number | Not specified                                                                                         |
| *archive abs change* | `archive_abs_change` | number | Not specified                                                                                         |
| *period*             | `period`             | number | 1000                                                                                                  |
| *archive period*     | `archive_period`     | number | Not specified                                                                                         |
| *__value*            | `__value`            | string | Not used yet                                                                                          |
| *__root_att*         | `__root_att`         | string | Not defined                                                                                           |

> **Note:**
> Both `delta_val` and `delta_t` MUST be set to non-default values
> in order for RDS (*read different than set*) alarms to work.

General properties:
* *description*: Providing textual information about the Attribute.
* *label*: Providing textual label to use as Attribute's name.
* *unit*: Providing textual representation of Attribute's unit.
* *standard unit*: Describing the conversion factor to transform Attribute's
  value into SI units. It MUST be a valid numerical value.
* *display unit*: Describing the conversion factor to transform Attribute's
  value into value usable in GUIs. It MUST be a valid numerical value.
* *format*: Describing how to convert Attribute's data to a textual
  representation. It MUST comply to
  [`printf`](http://man7.org/linux/man-pages/man3/printf.3.html)
  format string specification.
* *min value*: Describing the minimum value of Attribute's *set value*.
  * It MUST be defined only for Attributes with numerical *data type*.
  * It MUST be defined only for writable Attributes.
  * If defined:
    * It MUST be a valid numerical value.
    * It MUST be lower than *max value* (if specified).
* *max value*: Describing the maximum value of Attribute's *set value*.
  * It MUST be defined only for Attributes with numerical *data type*.
  * It MUST be defined only for writable Attributes.
  * If defined:
    * It MUST be a valid numerical value.
    * It MUST be greater than *min value* (if specified).

Properties for alarming purposes:
* *min alarm*: Describing the threshold value of Attribute's *read value*
  below which the attribute is considered as having alarm *quality* set to ALARM.
  * It MUST be defined only for Attributes with numerical *data type*.
  * If defined:
    * It MUST be a valid numerical value.
    * It MUST be lower than *max alarm* (if specified).
* *max alarm*: Describing the threshold value of Attribute's *read value*
  above which the attribute is considered as having alarm *quality*.
  * It MUST be defined only for Attributes with numerical *data type*.
  * If defined:
    * It MUST be a valid numerical value.
    * It MUST be greater than *min alarm* (if specified).
* *min warning*: Describing the threshold value of Attribute's *read value*
  below which the attribute is considered as having *quality* set to WARNING.
  * It MUST be defined only for Attributes with numerical *data type*.
  * If defined:
    * It MUST be a valid numerical value.
    * It MUST be lower than *max warning* (if specified).
* *max warning*: Describing the threshold value of Attribute's *read value*
  above which the attribute is considered as having *quality* set to WARNING.
  * It MUST be defined only for Attributes with numerical *data type*.
  * If defined:
    * It MUST be a valid numerical value.
    * It MUST be greater than *min warning* (if specified).
* *delta val*: Describing the maximum difference between Attribute's
  *read value* and *set value* after *delta t* time period,
  above which the attribute is considered as having *quality* set to ALARM.
  * It MUST be defined only for writable Attributes.
* *delta t*: describing the time period (in milliseconds) after which the
  difference between *read value* and *set value* must be lower than
  *delta val*. Otherwise the attribute is considered as having *quality* set to ALARM.
  * It MUST be defined only for writable Attributes.
  * It MUST be defined if *delta val* is also defined.

The alarm *quality* MUST take precedence over the warning *quality*.

Properties for event reporting purposes:
* *rel change*, *abs change*, *archive rel change*, *archive abs change*:
  describing the threshold values for relative and absolute change
  in Attribute's *read value* above which
  a *CHANGE* event or *ARCHIVE* event MUST be reported.
  * It MUST be either a valid numerical value
  or a pair of valid numerical values separated by a `,`.
  * If one value is specified, it MUST be used for both negative
  and positive change.
  * If two values are specified, the first MUST be used for negative change
  and the second MUST be used for positive change.
  * It MUST be defined only for Attributes with numerical *data type*.
* If relative change is specified, it MUST be expressed as a percentage change relative to the value reported in the previous event, e.g. a relative change of 1 will generate an event when:
  ```
  (current value - previous value) / previous value > 1%
  ```
* *period*, *archive period*: Describing the minimum time period
  in milliseconds after which a *PERIODIC* or *ARCHIVE* event MUST be reported,
  regardless of an Attribute's *read value*. If *period* is not specified,
  a default value of 1000 ms is used.

See [Attribute events section](#attribute-events) for more details.

```abnf
rel-change = change
abs-change = change

archive-rel-change = change
archive-abs-change = change

number = [ "-" ] 1*DIGIT [ "." ] *DIGIT
change = number [ "," number ]

period = 1*DIGIT
archive-period = period
```

### Attribute runtime parameters

At given point in time an Attribute MUST have associated:
* *quality*: An enumeration describing the state *read value*
  (one of *VALID*, *INVALID*, *ALARM*, *CHANGING*, *WARNING*).
* *read value*: An object representing the value of the Attribute.
  It MUST conform to *data format* and *data type*.
* *read dim x*: An integer describing the number of data elements in
  *read value* in X dimension.
    * If *data format* is *SCALAR*, it MUST be either 0 or 1.
    * If *data format* is *SPECTRUM* or *IMAGE*, it MUST be between 0 and
  *max dim x*.
* *read dim y*: An integer describing the number of data elements in
  *read value* in Y dimension.
    * If *data format* is *SCALAR* or *SPECTRUM*, it MUST be 0.
    * If *data format* is *IMAGE*, it MUST be between 0 and *max dim y*.

Additionally, if *writable* is *WRITE* or *READ_WRITE*,
at a given point in time an Attribute MUST have associated:
* *set value*: An object representing the value set to the Attribute.
  * It MUST conform to *data format* and *data type*.
* *write dim x*: An integer describing the number of data elements in
  *set value* in X dimension.
* *write dim y*: An integer describing the number of data elements in
  *set value* in Y dimension.


### Attribute aliases

A *full attribute name* consists of *device name* and *attribute name*
separated by a "/" character.

See [2/Device](../2/Device.md) for the definition of `<device-name>`.

An Attribute MAY have *alias* associated with it. An *alias* is a string which can be used
in place of *full attribute name* to address the Attribute.

An *alias* MUST follow the same naming specification as an *attribute name*.

See [16/TangoResourceLocator/Alias](../16/TangoResourceLocator.md### Alias) for common Alias properties.

### Attribute events

An Attribute can send following events:
* *PERIODIC*
* *CHANGE*
* *ARCHIVE*
* *DATA READY*
* *ATTR CONF*
* *USER*

Events can be sent automatically by a polling mechanism,
automatically by the Tango system or manually from the device server code.

The polling mechanism can send PERIODIC, CHANGE and ARCHIVE events.
In order to send events via the *polling mechanism*,
the polling for the Attribute MUST be enabled.
See [Attribute properties](#attribute-properties) section for conditions upon
which the events are sent with the polling enabled.
See [10/RequestReply](../10/RequestReply.md) for more details on polling configuration.

The Tango system MUST send ATTR CONF event whenever the Attribute configuration
is changed.
See [Attribute properties](#attribute-properties) section for a list of
modifiable attribute Properties.

The device server code can manually send *CHANGE*, *ARCHIVE*, *DATA READY*
and *USER* events without the need to configure the polling for the Attribute.


### Attribute naming schema

Formal specification of Attribute name is given below:
```ABNF
full-attribute-name = device-name "/" attribute-name
attribute-name = ALPHA *254acceptable-char
acceptable-char = ALPHA / DIGIT / underscore
underscore = %x5F
```
