How to use a forwarded attribute#
Definition#
Let’s take an example to explain what is a forwarded attribute. We assume we have to write a Tango class for a ski lift in a ski resort somewhere in the Alps. Obviously, the ski lift has a motor for which we already have a Tango class. This motor Tango class has one attribute speed. But for the ski lift, the motor speed is not the only thing which has to be controlled. For instance, you also want to give access to the wind sensor data installed on the top of the ski lift. Therefore, you write a ski-lift Tango class representing the whole ski-lift system. This ski-lift class will have at least two attributes which are:
The wind speed at the top of the ski-lift
The motor speed
The ski-lift Tango class motor speed attribute is nothing more than the motor Tango class speed attribute. All the ski-lift class has to do for this attribute is to forward the request (read/write) to the speed attribute of the motor Tango class. The speed attribute of the ski-lift Tango class is a forwarded attribute while the speed attribute of the motor Tango class is its root attribute.
A forwarded attribute get its configuration from its root attribute and it forwards to its root attribute:
Its read / write / write_read requests
Its configuration change
Its event subscription
Its locking behavior
As stated above, a forwarded attribute has the same configuration as its root attribute except its name and label which stays local. All other attribute configuration parameters are forwarded to the root attribute. If a root attribute configuration parameter is changed, the forwarded attribute is informed (via event) and its local configuration is also modified.
The association between the forwarded attribute and its root attribute
is done using a property named \_\_root_att
belonging to the forwarded attribute. This property value is simply the
name of the root attribute. Multi-control system is supported and this
\_\_root_att
attribute property value can be something like
tango://my_tango_host:10000/my/favorite/dev/the_root_attribute.
The name of the root attribute is included in the attribute configuration.
Polling has to be done on the root attribute. Polling a forwarded attribute
is not allow and an exception will be thrown if such a case happens.
If the root attribute is polled, a request to read the forwarded attribute
with the DeviceProxy object source parameter set to CACHE_DEVICE
or CACHE
will get its data from the root attribute polling buffer.
If you subscribe to events on a forwarded attribute, the subscription is forwarded to the root attribute. When the event is received by the forwarded attribute, the attribute name in the event data is modified to reflect the forwarded attribute name and the event is pushed to the original client(s).
When a device with forwarded attribute is locked, the device to which the root attribute belongs to is also locked.
Coding#
As explained in the section Writing a Tango device server, each Tango
class attribute is implemented via a C++ class which has to inherit from
either Attr*
, SpectrumAttr
or ImageAttr
according to the attribute
data format. For a forwarded attribute, the related class has to inherit
from the FwdAttr
class no matter what its data format is. For classical
attributes, the programmer can define in the Tango class code default
values for the attribute properties using one instance of the
UserDefaultAttrProp
class. For a forwarded attribute, the programmer has
to create one instance of the UserDefaultFwdAttrProp
class but only
the attribute label can be defined. One example of how to program a
forwarded attribute is given below:
1 class MyFwdAttr: public Tango::FwdAttr
2 {
3 public:
4 MyFwdAttr(const string &_n):FwdAttr(_n) {};
5 ~MyFwdAttr() {};
6 };
7
8 void DevTestClass::attribute_factory(vector<Tango::Attr *> &att_list)
9 {
10 ...
11 MyFwdAttr *att1 = new MyFwdAttr("fwd_att_name");
12 Tango::UserDefaultFwdAttrProp att1_prop;
13 att1_prop.set_label("Gasp a fwd attribute");
14 att1->set_default_properties(att1_prop);
15 att_list.push_back(att1);
16 ...
17 }
Line 1 : The forwarded attribute class inherits from FwdAttr
class.
Line 4-5 : Only constructor and destructor methods are required
Line 11 : The attribute object is created
Line 12-14 : A default value for the forwarded attribute label is defined.
Line 15: The forwarded attribute is added to the list of attribute
If there is an error in the forwarded attribute configuration (for instance
missing \_\_root_att
property), the attribute is not created by the
Tango kernel and is therefore not visible for the external world. The
state of the device to which the forwarded attribute belongs to is set
to ALARM (if not already FAULT) and a detailed error report is available
in the device status. In case a device with forwarded attribute(s) is
started before the device(s) with the root attribute(s), the same
principle is used: forwarded attribute(s) are not created, device state
is set to ALARM and device status reports the error. When the
device(s) with the root attribute starts, the forwarded attributes
will automatically be created.