#LyX 2.0 created this file. For more info see http://www.lyx.org/
\lyxformat 413
\begin_document
\begin_header
\textclass book
\begin_preamble
\usepackage{a4wide}
\end_preamble
\use_default_options false
\maintain_unincluded_children false
\language english
\language_package default
\inputencoding latin1
\fontencoding global
\font_roman default
\font_sans default
\font_typewriter default
\font_default_family default
\use_non_tex_fonts false
\font_sc false
\font_osf false
\font_sf_scale 100
\font_tt_scale 100

\graphics default
\default_output_format default
\output_sync 0
\bibtex_command default
\index_command default
\paperfontsize default
\spacing single
\use_hyperref false
\papersize default
\use_geometry false
\use_amsmath 1
\use_esint 0
\use_mhchem 1
\use_mathdots 1
\cite_engine basic
\use_bibtopic false
\use_indices false
\paperorientation portrait
\suppress_date false
\use_refstyle 0
\index Index
\shortcut idx
\color #008000
\end_index
\secnumdepth 5
\tocdepth 4
\paragraph_separation skip
\defskip medskip
\quotes_language english
\papercolumns 1
\papersides 2
\paperpagestyle default
\tracking_changes false
\output_changes false
\html_math_output 0
\html_css_as_file 0
\html_be_strict false
\end_header

\begin_body

\begin_layout Chapter
Writing a TANGO client using TANGO APIs
\end_layout

\begin_layout Section
Introduction
\end_layout

\begin_layout Standard
\noindent
TANGO devices and database are implemented using the TANGO device server
 model.
 To access them the user has the CORBA interface e.g.
 command_inout(), write_attributes() etc.
 defined by the idl file.
 These methods are very low-level and assume a good working knowledge of
 CORBA.
 In order to simplify this access, high-level api has been implemented which
 hides all CORBA aspects of TANGO.
 In addition the api hides details like how to connect to a device via the
 database, how to reconnect after a device has been restarted, how to correctly
 pack and unpack attributes and so on by implementing these in a manner
 transparent to the user.
 The api provides a unified error handling for all TANGO and CORBA errors.
 Unlike the CORBA C++ bindings the TANGO api supports native C++ data types
 e.g.
 strings and vectors.
\end_layout

\begin_layout Standard
This chapter describes how to use these API's.
 It is not a reference guide.
 Reference documentation is available as Web pages in the 
\begin_inset CommandInset href
LatexCommand href
name "Tango Web site"
target "http://www.tango-controls.org"

\end_inset


\end_layout

\begin_layout Section
\noindent
Getting Started
\end_layout

\begin_layout Standard
Refer to the chapter "Getting Started" for an example on getting start with
 the C++ or Java api.
\end_layout

\begin_layout Section
\noindent
Basic Philosophy
\end_layout

\begin_layout Standard
\noindent
The basic philosophy is to have high level classes to deal with Tango devices.
 To communicate with Tango device, uses the 
\series bold
DeviceProxy
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DeviceProxy
\end_layout

\end_inset


\series default
 class.
 To send/receive data to/from Tango device, uses the 
\series bold
DeviceData
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DeviceData
\end_layout

\end_inset

, DeviceAttribute
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DeviceAttribute
\end_layout

\end_inset


\series default
 or 
\series bold
DevicePipe
\series default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DevicePipe
\end_layout

\end_inset

 classes.
 To communicate with a group of devices, use the 
\series bold
Group
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
Group
\end_layout

\end_inset


\series default
 class.
 If you are interested only in some attributes provided by a Tango device,
 uses the 
\series bold
AttributeProxy
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
AttributeProxy
\end_layout

\end_inset


\series default
 class.
 Even if the Tango database is implemented as any other devices (and therefore
 accessible with one instance of a DeviceProxy class), specific high level
 classes have been developped to query it.
 Uses the 
\series bold
Database
\series default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
Database
\end_layout

\end_inset

, 
\series bold
DbDevice
\series default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DbDevice
\end_layout

\end_inset

, 
\series bold
DbClass
\series default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DbClass
\end_layout

\end_inset

, 
\series bold
DbServer
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DbServer
\end_layout

\end_inset


\series default
 or 
\series bold
DbData
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DbData
\end_layout

\end_inset


\series default
 classes when interfacing the Tango database.
 Callback for asynchronous requests or events are implemented via a 
\series bold
CallBack
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
CallBack
\end_layout

\end_inset


\series default
 class.
 An utility class called 
\series bold
ApiUtil
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
 ApiUtil
\end_layout

\end_inset


\series default
 is also available.
\end_layout

\begin_layout Section
Data types
\end_layout

\begin_layout Standard
The definition of the basic data type you can transfert using Tango is:
\end_layout

\begin_layout Standard
\begin_inset VSpace 0.3cm
\end_inset


\end_layout

\begin_layout Standard
\align center
\begin_inset Tabular
<lyxtabular version="3" rows="17" columns="2">
<features islongtable="true" longtabularalignment="center">
<column alignment="center" valignment="top" width="0pt">
<column alignment="center" valignment="top" width="0pt">
<row>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Tango type name
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
C++ equivalent type
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevBoolean
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
boolean
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevShort
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
short
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevEnum
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
enumeration (only for attribute / See chapter on advanced features)
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevLong
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
int (always 32 bits data)
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevLong64
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
long long on 32 bits chip or long on 64 bits chip
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
always 64 bits data
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevFloat
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
float
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevDouble
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevString
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
char *
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevEncoded
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
structure with 2 fields: a string and an array of unsigned char
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevUChar
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
unsigned char
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevUShort
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
unsigned short
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevULong
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
unsigned int (always 32 bits data)
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevULong64
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
unsigned long long on 32 bits chip or unsigned long on 64 bits chip
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
always 64 bits data
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
DevState
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Tango specific data type
\end_layout

\end_inset
</cell>
</row>
</lyxtabular>

\end_inset


\end_layout

\begin_layout Standard
\begin_inset VSpace 0.3cm
\end_inset


\end_layout

\begin_layout Standard
Using commands, you are able to transfert all these data types, array of
 these basic types and two other Tango specific data types called DevVarLongStri
ngArray and DevVarDoubleStringArray.
 See chapter 
\begin_inset CommandInset ref
LatexCommand ref
reference "Data exchange"

\end_inset

 to get details about them.
 You are also able to create attributes using any of these basic data types
 to transfer data between clients and servers.
\end_layout

\begin_layout Section
Request model
\begin_inset CommandInset label
LatexCommand label
name "sec:Request-model"

\end_inset


\end_layout

\begin_layout Standard
For the most important API remote calls (command_inout, read_attribute(s)
 and write_attribute(s)), Tango supports two kind of requests which are
 the synchronous model and the asynchronous model.
 Synchronous
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
synchronous
\end_layout

\end_inset

 model means that the client wait (and is blocked) for the server to send
 an answer.
 Asynchronous
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
asynchronous
\end_layout

\end_inset

 model means that the client does not wait for the server to send an answer.
 The client sends the request and immediately returns allowing the CPU to
 do anything else (like updating a graphical user interface).
 Device pipe
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
pipe
\end_layout

\end_inset

 supports only the synchronous model.
 Within Tango, there are two ways to retrieve the server answer when using
 asynchronous model.
 They are:
\end_layout

\begin_layout Enumerate
The polling
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
polling
\end_layout

\end_inset

 mode
\end_layout

\begin_layout Enumerate
The callback
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
callback
\end_layout

\end_inset

 mode
\end_layout

\begin_layout Standard
In polling mode, the client executes a specific call to check if the answer
 is arrived.
 If this is not the case, an exception is thrown.
 If the reply is there, it is returned to the caller and if the reply was
 an exception, it is re-thrown.
 There are two calls to check if the reply is arrived:
\end_layout

\begin_layout Itemize
Call which does not wait before the server answer is returned to the caller.
\end_layout

\begin_layout Itemize
Call which wait with timeout before returning the server answer to the caller
 (or throw the exception) if the answer is not arrived.
\end_layout

\begin_layout Standard
In callback model, the caller must supply a callback method which will be
 executed when the command returns.
 They are two sub-modes:
\end_layout

\begin_layout Enumerate
The pull
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
pull
\end_layout

\end_inset

 callback mode
\end_layout

\begin_layout Enumerate
The push
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
push
\end_layout

\end_inset

 callback mode
\end_layout

\begin_layout Standard
In the pull callback
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
callback
\end_layout

\end_inset

 mode, the callback is triggered if the server answer is arrived when the
 client decide it by calling a 
\emph on
synchronization
\emph default
 method (The client pull-out the answer).
 In push mode, the callback is executed as soon as the reply arrives in
 a separate thread (The server pushes the answer to the client).
\end_layout

\begin_layout Subsection
Synchronous model
\end_layout

\begin_layout Standard
Synchronous access to Tango device are provided using the 
\emph on
DeviceProxy
\emph default
 or 
\emph on
AttributeProxy
\emph default
 class.
 For the 
\emph on
DeviceProxy
\emph default
 class, the main synchronous call methods are :
\end_layout

\begin_layout Itemize

\emph on
command_inout()
\emph default
 to execute a Tango device command
\end_layout

\begin_layout Itemize

\emph on
read_attribute()
\emph default
 or 
\emph on
read_attributes()
\emph default
 to read a Tango device attribute(s)
\end_layout

\begin_layout Itemize

\emph on
write_attribute()
\emph default
 or 
\emph on
write_attributes()
\emph default
 to write a Tango device attribute(s)
\end_layout

\begin_layout Itemize

\emph on
write_read_attribute()
\emph default
 or 
\emph on
write_read_attributes()
\emph default
 to write then read Tango device attribute(s)
\end_layout

\begin_layout Itemize

\emph on
read_pipe()
\emph default
 to read a Tango device pipe
\end_layout

\begin_layout Itemize

\emph on
write_pipe()
\emph default
 to write a Tango device pipe
\end_layout

\begin_layout Itemize

\emph on
write_read_pipe()
\emph default
 to write then read Tango device pipe
\end_layout

\begin_layout Standard
For commands, data are send/received to/from device using the 
\emph on
DeviceData
\emph default
 class.
 For attributes, data are send/received to/from device attribute using the
 
\emph on
DeviceAttribute
\emph default
 class.
 For pipes, data are send/receive to/from device pipe using the 
\emph on
DevicePipe
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout

\emph off
DevicePipe
\end_layout

\end_inset


\emph default
 and 
\emph on
DevicePipeBlob
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout

\emph off
DevicePipeBlob
\end_layout

\end_inset


\emph default
 classes.
\end_layout

\begin_layout Standard
In some cases, only attributes provided by a Tango device are interesting
 for the application.
 You can use the 
\emph on
AttributeProxy
\emph default
 class.
 Its main synchronous methods are :
\end_layout

\begin_layout Itemize

\emph on
read()
\emph default
 to read the attribute value
\end_layout

\begin_layout Itemize

\emph on
write()
\emph default
 to write the attribute value
\end_layout

\begin_layout Itemize

\emph on
write_read()
\emph default
 to write then read the attribute value
\end_layout

\begin_layout Standard
Data are transmitted using the 
\emph on
DeviceAttribute
\emph default
 class.
\end_layout

\begin_layout Subsection
Asynchronous model
\end_layout

\begin_layout Standard
Asynchronous access to Tango device are provided using 
\emph on
DeviceProxy
\emph default
 or 
\emph on
AttributeProxy, CallBack
\emph default
 and 
\emph on
ApiUtil
\emph default
 classes methods.
 The main asynchronous call methods and used classes are :
\end_layout

\begin_layout Itemize
To execute a command on a device
\end_layout

\begin_deeper
\begin_layout Itemize

\emph on
DeviceProxy::command_inout_asynch()
\emph default
 and 
\emph on
DeviceProxy::command_inout_reply()
\emph default
 in polling model.
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::command_inout_asynch()
\emph default
, 
\emph on
DeviceProxy::get_asynch_replies()
\emph default
 and 
\emph on
CallBack
\emph default
 class in callback pull model
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::command_inout_asynch()
\emph default
, 
\emph on
ApiUtil::set_asynch_cb_sub_model()
\emph default
 and 
\emph on
CallBack
\emph default
 class in callback push model
\end_layout

\end_deeper
\begin_layout Itemize
To read a device attribute 
\end_layout

\begin_deeper
\begin_layout Itemize

\emph on
DeviceProxy::read_attribute_asynch()
\emph default
 and 
\emph on
DeviceProxy::read_attribute_reply()
\emph default
 in polling model
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::read_attribute_asynch()
\emph default
, 
\emph on
DeviceProxy::get_asynch_replies()
\emph default
 and 
\emph on
CallBack
\emph default
 class in callback pull model.
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::read_attribute_asynch()
\emph default
, 
\emph on
ApiUtil::set_asynch_cb_sub_model()
\emph default
 and 
\emph on
CallBack
\emph default
 class in callback push model
\end_layout

\end_deeper
\begin_layout Itemize
To write a device attribute
\end_layout

\begin_deeper
\begin_layout Itemize

\emph on
DeviceProxy::write_attribute_asynch()
\emph default
 in polling model
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::write_attribute_asynch()
\emph default
 and 
\emph on
CallBack
\emph default
 class in callback pull model
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::write_attribute_asynch()
\emph default
, 
\emph on
ApiUtil::set_asynch_cb_sub_model()
\emph default
 and 
\emph on
CallBack
\emph default
 class in callback push model
\end_layout

\end_deeper
\begin_layout Standard
For commands, data are send/received to/from device using the 
\emph on
DeviceData
\emph default
 class.
 For attributes, data are send/received to/from device attribute using the
 
\emph on
DeviceAttribute
\emph default
 class.
 It is also possible to generate asynchronous request(s) using the 
\emph on
AttributeProxy
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
AttributeProxy
\end_layout

\end_inset


\emph default
 class following the same schema than above.
 Methods to use are :
\end_layout

\begin_layout Itemize

\emph on
read_asynch(
\emph default
) and 
\emph on
read_reply()
\emph default
 to asynchronously read the attribute value
\end_layout

\begin_layout Itemize

\emph on
write_asynch()
\emph default
 and 
\emph on
write_reply()
\emph default
 to asynchronously write the attribute value
\end_layout

\begin_layout Section
Events
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
event
\end_layout

\end_inset


\end_layout

\begin_layout Subsection
Introduction
\end_layout

\begin_layout Standard
Events are a critical part of any distributed control system.
 Their aim is to provide a communication mechanism which is fast and efficient.
 
\end_layout

\begin_layout Standard
The standard CORBA communication paradigm is a synchronous or asynchronous
 two-way call.
 In this paradigm the call is initiated by the client who contacts the server.
 The server handles the client's request and sends the answer to the client
 or throws an exception which the client catches.
 This paradigm involves two calls to receive a single answer and requires
 the client to be active in initiating the request.
 If the client has a permanent interest in a value he is obliged to poll
 the server for an update in a value every time.
 This is not efficient in terms of network bandwidth nor in terms of client
 programming.
\end_layout

\begin_layout Standard
For clients who are permanently interested in values the event-driven communicat
ion paradigm is a more efficient and natural way of programming.
 In this paradigm the client registers her interest once in an event (value).
 After that the server informs the client every time the event has occurred.
 This paradigm avoids the client polling, frees it for doing other things,
 is fast and makes efficient use of the network.
\end_layout

\begin_layout Standard
The rest of this chapter explains how the TANGO events are implemented and
 the application programmer's interface.
\end_layout

\begin_layout Subsection
Event definition
\end_layout

\begin_layout Standard
TANGO events represent an alternative channel for reading TANGO device attribute
s
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
attribute
\end_layout

\end_inset

.
 Device attributes values are sent to all subscribed clients when an event
 occurs.
 Events can be an attribute value change, a change in the data quality or
 a periodically send event.
 The clients continue receiving events as long as they stay subscribed.
 Most of the time, the device server polling thread detects the event and
 then pushes the device attribute value to all clients.
 Nevertheless, in some cases, the delay introduced by the polling thread
 in the event propagation is detrimental.
 For such cases, some API calls directly push the event.
 Until TANGO release 8, the omniNotify
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
omniNotify
\end_layout

\end_inset

 implementation of the CORBA Notification service
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
Notification Service
\end_layout

\end_inset

 was used to dispatch events.
 Starting with TANGO 8, this CORBA Notification service has been replaced
 by the ZMQ
\begin_inset Index idx
status open

\begin_layout Plain Layout
ZMQ
\end_layout

\end_inset

 library which implements a Publish/Subscribe communication model well adapted
 to TANGO events communication.
\end_layout

\begin_layout Subsection
Event types
\end_layout

\begin_layout Standard
The following eight event types have been implemented in TANGO :
\end_layout

\begin_layout Enumerate

\series bold
change
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
change
\end_layout

\end_inset


\series default
 - an event is triggered and the attribute value is sent when the attribute
 value changes significantly.
 The exact meaning of significant is device attribute dependent.
 For analog and digital values this is a delta fixed per attribute, for
 string values this is any non-zero change i.e.
 if the new attribute value is not equal to the previous attribute value.
 The delta can either be specified as a relative or absolute change.
 The delta is the same for all clients unless a filter is specified (see
 below).
 To easily write applications using the change event, it is also triggered
 in the following case :
\end_layout

\begin_deeper
\begin_layout Enumerate
When a spectrum or image attribute size changes.
\end_layout

\begin_layout Enumerate
At event subscription time
\end_layout

\begin_layout Enumerate
When the polling thread receives an exception during attribute reading
\end_layout

\begin_layout Enumerate
When the polling thread detects that the attribute quality factor has changed.
\end_layout

\begin_layout Enumerate
The first good reading of the attribute after the polling thread has received
 exception when trying to read the attribute
\end_layout

\begin_layout Enumerate
The first time the polling thread detects that the attribute quality factor
 has changed from INVALID to something else
\end_layout

\begin_layout Enumerate
When a change event is pushed manually from the device server code.
 (
\emph on
DeviceImpl::push_change_event()
\emph default
).
\end_layout

\begin_layout Enumerate
By the methods Attribute::set_quality() and Attribute::set_value_date_quality()
 if a client has subscribed to the change event on the attribute.
 This has been implemented for cases where the delay introduced by the polling
 thread in the event propagation is not authorized.
\end_layout

\end_deeper
\begin_layout Enumerate

\series bold
periodic
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
periodic
\end_layout

\end_inset


\series default
 - an event is sent at a fixed periodic interval.
 The frequency of this event is determined by the 
\emph on
event_period
\emph default
 property of the attribute and the polling frequency.
 The polling frequency determines the highest frequency at which the attribute
 is read.
 The event_period determines the highest frequency at which the periodic
 event is sent.
 Note if the event_period is not an integral number of the polling period
 there will be a beating of the two frequencies
\begin_inset Foot
status collapsed

\begin_layout Plain Layout
note: the polling is not synchronized is currently not synchronized on the
 hour
\end_layout

\end_inset

.
 Clients can reduce the frequency at which they receive periodic events
 by specifying a filter on the periodic event counter.
 
\end_layout

\begin_layout Enumerate

\series bold
archive
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
archive
\end_layout

\end_inset


\series default
 - an event is sent if one of the archiving conditions is satisfied.
 Archiving conditions are defined via properties in the database.
 These can be a mixture of delta_change and periodic.
 Archive events can be send from the polling thread or can be manually pushed
 from the device server code (
\emph on
DeviceImpl::push_archive_event()
\emph default
).
\end_layout

\begin_layout Enumerate

\series bold
attribute configuration
\series default
 - an event is sent if the attribute configuration is changed.
\end_layout

\begin_layout Enumerate

\series bold
data ready
\series default
 - This event is sent when coded by the device server programmer who uses
 a specific method of one of the Tango device server class to fire the event
 (
\emph on
DeviceImpl::push_data_ready_event()
\emph default
).
 The rule of this event is to inform a client that it is now possible to
 read an attribute.
 This could be useful in case of attribute with many data.
\end_layout

\begin_layout Enumerate

\series bold
user
\series default
 - The criteria and configuration of these user events are managed by the
 device server programmer who uses a specific method of one of the Tango
 device server class to fire the event (
\emph on
DeviceImpl::push_event()
\emph default
).
\end_layout

\begin_layout Enumerate

\series bold
device interface change
\series default
 - This event is sent when the device interface changes.
 Using Tango, it is possible to dynamically add/remove attribute/command
 to a device.
 This event is the way to inform client(s) that attribute/command has been
 added/removed from a device.
 Note that this type of event is attached to a device and not to one attribute
 (like all other event types).
 This event is triggered in the following case :
\end_layout

\begin_deeper
\begin_layout Enumerate
A dynamic attribute or command is added or removed.
 The event is sent after a small delay (50 mS) in order to eliminate the
 risk of events storm in case several attributes/commands are added/removed
 in a loop 
\end_layout

\begin_layout Enumerate
At the end of admin device RestartServer or DevRestart command
\end_layout

\begin_layout Enumerate
After a re-connection due to a device server restart.
 Because the device interface is not memorized, the event is sent even if
 it is highly possible that the device interface has not changed.
 A flag in the data propagated with the event inform listening applications
 that the device interface change is not guaranteed.
 
\end_layout

\begin_layout Enumerate
At event re-connection time.
 This case is similar to the previous one (device interface change not guarantee
d)
\end_layout

\end_deeper
\begin_layout Enumerate

\series bold
pipe
\series default
 - This is the kind of event which has to be used when the user want to
 push data through a pipe.
 This kind of event is only sent by the user code by using a specific method
 (
\emph on
DeviceImpl::push_pipe_event()
\emph default
).
 There is no way to ask the Tango kernel to automatically push this kind
 of event.
\end_layout

\begin_layout Standard
The first three above events are automatically generated by the TANGO library
 or fired by the user code.
 Events number 4 and 7 are only automatically sent by the library and events
 5, 6 and 8 are fired only by the user code.
\end_layout

\begin_layout Subsection
Event filtering (Removed in Tango release 8 and above)
\end_layout

\begin_layout Standard
Please, note that this feature is available only for Tango releases older
 than Tango 8.
 The CORBA Notification Service allows event filtering.
 This means that a client can ask the Notification Service to send the event
 only if some filter is evaluated to true.
 Within the Tango control system, some pre-defined fields can be used as
 filter.
 These fields depend on the event type.
\end_layout

\begin_layout Standard
\begin_inset VSpace 0.3cm
\end_inset


\end_layout

\begin_layout Standard
\align center
\begin_inset Tabular
<lyxtabular version="3" rows="18" columns="4">
<features islongtable="true" longtabularalignment="center">
<column alignment="center" valignment="top" width="0pt">
<column alignment="center" valignment="top" width="0in">
<column alignment="center" valignment="top" width="0in">
<column alignment="center" valignment="top" width="0in">
<row>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Event type
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Filterable field name
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Filterable field value
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
type
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
delta_change_rel
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Relative change (in %) since last event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
delta_change_abs
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Absolute change since last event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
change
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
quality
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Is set to 1 when the attribute quality factor has
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
changed, otherwise it is 0
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\family roman
\series medium
\shape up
\size normal
\emph off
\bar no
\noun off
\color none
forced_event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Is set to 1 when the event was fired on exception 
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
or a quality factor set to invalid
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
periodic
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
counter
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Incremented each time the event is sent
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
long
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
delta_change_rel
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Relative change (in %) since last event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
delta_change_abs
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Absolute change since last event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" bottomline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
quality
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Is set to 1 when the attribute quality factor has
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
changed, otherwise it is 0
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
archive
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Incremented each time the event is sent
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" topline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
counter
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
for periodic reason.
 Set to -1 if event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
long
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
sent for change reason
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\family roman
\series medium
\shape up
\size normal
\emph off
\bar no
\noun off
\color none
forced_event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Is set to 1 when the event was fired on exception
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
<row>
<cell multicolumn="1" alignment="center" valignment="top" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
or a quality factor set to invalid
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
</row>
<row>
<cell alignment="center" valignment="top" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout

\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" leftline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
delta_event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
Number of milli-seconds since previous event
\end_layout

\end_inset
</cell>
<cell alignment="center" valignment="top" bottomline="true" rightline="true" usebox="none">
\begin_inset Text

\begin_layout Plain Layout
double
\end_layout

\end_inset
</cell>
</row>
</lyxtabular>

\end_inset


\end_layout

\begin_layout Standard
\begin_inset VSpace 0.3cm
\end_inset


\end_layout

\begin_layout Standard
Filter are defined as a string following a grammar defined by CORBA.
 It is defined in 
\begin_inset CommandInset citation
LatexCommand cite
key "Notif_doc"

\end_inset

.
 The following example shows you the most common use of these filters in
 the Tango world :
\end_layout

\begin_layout Itemize
To receive periodic event one out of every three, the filter must be 
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
begin{center}
\end_layout

\end_inset

"$counter % 3 == 0"
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
end{center}
\end_layout

\end_inset


\end_layout

\begin_layout Itemize
To receive change event only if the relative change is greater than 20 %
 (positive and negative), the filter must be 
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
begin{center}
\end_layout

\end_inset

"$delta_change_rel >= 20 or $delta_change_rel <= -20"
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
end{center}
\end_layout

\end_inset


\end_layout

\begin_layout Itemize
To receive a change event only on quality change, the filter must be 
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
begin{center}
\end_layout

\end_inset

"$quality == 1"
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
end{center}
\end_layout

\end_inset


\end_layout

\begin_layout Standard
For user events, the filter field name(s) and their value are defined by
 the device server programmer.
\end_layout

\begin_layout Subsection
Application Programmer's Interface
\end_layout

\begin_layout Standard
How to setup and use the TANGO events ? The interfaces described here are
 intended as user friendly interfaces to the underlying CORBA calls.
 The interface is modeled after the asynchronous
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
asynchronous
\end_layout

\end_inset

 
\emph on
command_inout()
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
command-inout()
\end_layout

\end_inset


\emph default
 interface so as to maintain coherency.
 The event system supports 
\series bold
push callback model
\series default
 as well as the 
\series bold
pull callback model.
\end_layout

\begin_layout Standard
The two event reception modes are:
\end_layout

\begin_layout Itemize

\series bold
Push callback model
\series default
 : On event reception a callbacks method gets immediately executed.
\end_layout

\begin_layout Itemize

\series bold
Pull callback model
\series default
 : The event will be buffered the client until the client is ready to receive
 the event data.
 The client triggers the execution of the callback method.
\end_layout

\begin_layout Standard
The event reception buffer in the 
\series bold
pull callback model
\series default
, is implemented as a round robin buffer.
 The client can choose the size when subscribing for the event.
 This way the client can set-up different ways to receive events.
\end_layout

\begin_layout Itemize
Event reception buffer size = 1 : The client is interested only in the value
 of the last event received.
 All other events that have been received since the last reading are discarded.
\end_layout

\begin_layout Itemize
Event reception buffer size > 1 : The client has chosen to keep an event
 history of a given size.
 When more events arrive since the last reading, older events will be discarded.
\end_layout

\begin_layout Itemize
Event reception buffer size = ALL_EVENTS : The client buffers all received
 events.
 The buffer size is unlimited and only restricted by the available memory
 for the client.
\end_layout

\begin_layout Subsubsection
Configuring events
\end_layout

\begin_layout Standard
The attribute configuration set is used to configure under what conditions
 events
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
event
\end_layout

\end_inset

 are generated.
 A set of standard attribute properties (part of the standard attribute
 configuration) are read from the database at device startup time and used
 to configure the event engine.
 If there are no properties defined then default values specified in the
 code are used.
 
\end_layout

\begin_layout Paragraph
change
\end_layout

\begin_layout Standard
The attribute properties and their default values for the "change" event
 are :
\end_layout

\begin_layout Enumerate

\series bold
rel_change
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
rel-change
\end_layout

\end_inset


\series default
 - a property of maximum 2 values.
 It specifies the positive and negative 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.
 If only one property is specified then it is used for the positive and
 negative change.
 If no property is specified, no events are generated.
\end_layout

\begin_layout Enumerate

\series bold
abs_change
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
abs-change
\end_layout

\end_inset


\series default
 - a property of maximum 2 values.It specifies the positive and negative
 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 property is specified then it is used for the positive and
 negative change.
 If no properties are specified then the relative change is used.
\end_layout

\begin_layout Paragraph
periodic
\end_layout

\begin_layout Standard
The attribute properties and their default values for the "periodic" event
 are :
\end_layout

\begin_layout Enumerate

\series bold
event_period
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
event-period
\end_layout

\end_inset


\series default
 - the minimum time between events (in milliseconds).
 If no property is specified then a default value of 1 second is used.
\end_layout

\begin_layout Paragraph
archive
\end_layout

\begin_layout Standard
The attribute properties and their default values for the "archive" event
 are :
\end_layout

\begin_layout Enumerate

\series bold
archive_rel_change
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
archive-rel-change
\end_layout

\end_inset


\series default
 - a 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 no events are generate.
\end_layout

\begin_layout Enumerate

\series bold
archive_abs_change
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
archive-abs-change
\end_layout

\end_inset


\series default
 - a 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.
\end_layout

\begin_layout Enumerate

\series bold
archive_period
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
archive-period
\end_layout

\end_inset


\series default
 - the minimum time between archive events (in milliseconds).
 If no property is specified, no periodic archiving events are send.
\end_layout

\begin_layout Subsubsection
C++ Clients
\end_layout

\begin_layout Standard
This is the interface for clients who want to receive events
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
event
\end_layout

\end_inset

.
 The main action of the client is to subscribe and unsubscribe to events.
 Once the client has subscribed to one or more events the events are received
 in a separate thread by the client.
\end_layout

\begin_layout Standard
Two reception modes are possible:
\end_layout

\begin_layout Itemize
On event reception a callbacks method gets immediately executed.
\end_layout

\begin_layout Itemize
The event will be buffered until the client until the client is ready to
 receive the event data.
\end_layout

\begin_layout Standard
The mode to be used has to be chosen when subscribing for the event.
\end_layout

\begin_layout Paragraph
Subscribing to events
\end_layout

\begin_layout Standard
The client call to subscribe to an event is named 
\emph on
DeviceProxy::subscribe_event()
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
subscribe-event
\end_layout

\end_inset


\emph default
 .
 During the event subscription the client has to choose the event reception
 mode to use.
 
\end_layout

\begin_layout Standard

\series bold
Push model
\series default
:
\end_layout

\begin_layout Verbatim
int DeviceProxy::subscribe_event( 
\end_layout

\begin_layout Verbatim
             const string &attribute, 
\end_layout

\begin_layout Verbatim
             Tango::EventType event, 
\end_layout

\begin_layout Verbatim
             Tango::CallBack *callback,
\end_layout

\begin_layout Verbatim
             bool stateless = false);
\end_layout

\begin_layout Standard
The client implements a callback method which is triggered when the event
 is received.
 Note that this callback method will be executed by a thread started by
 the underlying ORB.
 This thread is not the application main thread.
 For Tango releases before 8, a similar call with one extra parameter for
 event filtering is also available.
\end_layout

\begin_layout Standard

\series bold
Pull model
\series default
:
\end_layout

\begin_layout Verbatim
int DeviceProxy::subscribe_event( 
\end_layout

\begin_layout Verbatim
             const string &attribute, 
\end_layout

\begin_layout Verbatim
             Tango::EventType event, 
\end_layout

\begin_layout Verbatim
             int event_queue_size,
\end_layout

\begin_layout Verbatim
             bool stateless = false);
\end_layout

\begin_layout Standard
The client chooses the size of the round robin event reception buffer.
 Arriving events will be buffered until the client uses 
\emph on
DeviceProxy::get_events()
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
get-events
\end_layout

\end_inset


\emph default
 to extract the event data.
 For Tango releases before 8, a similar call with one extra parameter for
 event filtering is also available.
\end_layout

\begin_layout Standard
On top of the user filter defined by the 
\emph on
filters
\emph default
 parameter, basic filtering is done based on the reason specified and the
 event type.
 For example when reading the state and the reason specified is "change"
 the event will be fired only when the state changes.
 Events consist of an attribute name and the event reason.
 A standard set of reasons are implemented by the system, additional device
 specific reasons can be implemented by device servers programmers.
 
\end_layout

\begin_layout Standard
The stateless flag = false indicates that the event subscription will only
 succeed when the given attribute is known and available in the Tango system.
 Setting stateless = true will make the subscription succeed, even if an
 attribute of this name was never known.
 The real event subscription will happen when the given attribute will be
 available in the Tango system.
\end_layout

\begin_layout Standard
Note that in this model, the callback method will be executed by the thread
 doing the 
\emph on
DeviceProxy::get_events()
\emph default
 call.
\end_layout

\begin_layout Paragraph
The CallBack class
\end_layout

\begin_layout Standard
In C++, the client has to implement a class inheriting from the Tango CallBack
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
CallBack
\end_layout

\end_inset

 class and pass this to the 
\emph on
DeviceProxy::subscribe_event()
\emph default
 method.
 The CallBack class is the same class as the one proposed for the TANGO
 asynchronous call.
 This is as follows for events :
\end_layout

\begin_layout Verbatim
class MyCallback : public Tango::CallBack
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
   .
\end_layout

\begin_layout Verbatim
   .
\end_layout

\begin_layout Verbatim
   .
\end_layout

\begin_layout Verbatim
   virtual push_event(Tango::EventData *);
\end_layout

\begin_layout Verbatim
   virtual push_event(Tango::AttrConfEventData *);
\end_layout

\begin_layout Verbatim
   virtual push_event(Tango::DataReadyEventData *);
\end_layout

\begin_layout Verbatim
   virtual push_event(Tango::DevIntrChangeEventData *);
\end_layout

\begin_layout Verbatim
   virtual push_event(Tango::PipeEventData *);
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
where EventData
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
EventData
\end_layout

\end_inset

 is defined as follows :
\end_layout

\begin_layout Verbatim
class EventData 
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
   DeviceProxy       *device;
\end_layout

\begin_layout Verbatim
   string            attr_name;
\end_layout

\begin_layout Verbatim
   string            event;
\end_layout

\begin_layout Verbatim
   DeviceAttribute   *attr_value;
\end_layout

\begin_layout Verbatim
   bool              err;
\end_layout

\begin_layout Verbatim
   DevErrorList      errors;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
AttrConfEventData
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
AttrConfEventData
\end_layout

\end_inset

 is defined as follows :
\end_layout

\begin_layout Verbatim
class AttrConfEventData 
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
   DeviceProxy       *device;
\end_layout

\begin_layout Verbatim
   string            attr_name;
\end_layout

\begin_layout Verbatim
   string            event;
\end_layout

\begin_layout Verbatim
   AttributeInfoEx   *attr_conf;
\end_layout

\begin_layout Verbatim
   bool              err;
\end_layout

\begin_layout Verbatim
   DevErrorList      errors;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
DataReadyEventData
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DataReadyEventData
\end_layout

\end_inset

 is defined as follows :
\end_layout

\begin_layout Verbatim
class DataReadyEventData 
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
   DeviceProxy       *device;
\end_layout

\begin_layout Verbatim
   string            attr_name;
\end_layout

\begin_layout Verbatim
   string            event;
\end_layout

\begin_layout Verbatim
   int               attr_data_type;
\end_layout

\begin_layout Verbatim
   int               ctr;
\end_layout

\begin_layout Verbatim
   bool              err;
\end_layout

\begin_layout Verbatim
   DevErrorList      errors;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
DevIntrChangeEventData
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DevIntrChangeEventData
\end_layout

\end_inset

 is defined as follows :
\end_layout

\begin_layout Verbatim
class DevIntrChangeEventData 
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
   DeviceProxy            device;
\end_layout

\begin_layout Verbatim
   string                 event;
\end_layout

\begin_layout Verbatim
   string                 device_name;
\end_layout

\begin_layout Verbatim
   CommandInfoList        cmd_list;
\end_layout

\begin_layout Verbatim
   AttributeInfoListEx    att_list;
\end_layout

\begin_layout Verbatim
   bool                   dev_started;
\end_layout

\begin_layout Verbatim
   bool                   err;
\end_layout

\begin_layout Verbatim
   DevErrorList           errors;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
and PipeEventData
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
PipeEventData
\end_layout

\end_inset

 is defined as follows :
\end_layout

\begin_layout Verbatim
class PipeEventData 
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
   DeviceProxy       *device;
\end_layout

\begin_layout Verbatim
   string            pipe_name;
\end_layout

\begin_layout Verbatim
   string            event;
\end_layout

\begin_layout Verbatim
   DevicePipe        *pipe_value;
\end_layout

\begin_layout Verbatim
   bool              err;
\end_layout

\begin_layout Verbatim
   DevErrorList      errors;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
In push model, there are some cases (same callback used for events coming
 from different devices hosted in device server process running on different
 hosts) where the callback method could be executed concurently by different
 threads started by the ORB.
 The user has to code his callback method in a 
\series bold
thread
\series default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
thread
\end_layout

\end_inset

 
\series bold
safe
\series default
 manner.
\end_layout

\begin_layout Paragraph
Unsubscribing from an event 
\end_layout

\begin_layout Standard
Unsubscribe a client from receiving the event specified by 
\emph on
event_id
\emph default
 is done by calling the 
\emph on
DeviceProxy::unsubscribe_event()
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
unsubscribe-event
\end_layout

\end_inset


\emph default
 method :
\end_layout

\begin_layout Verbatim
void DeviceProxy::unsubscribe_event(int event_id);
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Paragraph
Extract buffered event data
\end_layout

\begin_layout Standard
When the pull model was chosen during the event subscription, the received
 event data can be extracted with 
\emph on
DeviceProxy::get_events()
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
get-events
\end_layout

\end_inset

.

\emph default
 Two possibilities are available for data extraction.
 Either a callback method can be executed for every event in the buffer
 when using
\end_layout

\begin_layout Verbatim
int DeviceProxy::get_events( 
\end_layout

\begin_layout Verbatim
             int event_id, 
\end_layout

\begin_layout Verbatim
             CallBack *cb);
\end_layout

\begin_layout Standard
Or all the event data can be directly extracted as EventDataList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
EventDataList
\end_layout

\end_inset

, AttrConfEventDataList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
AttrConfEventDataList
\end_layout

\end_inset

 , DataReadyEventDataList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DataReadyEventDataList
\end_layout

\end_inset

, DevIntrChangeEventDataList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DevIntrChangeEventDataList
\end_layout

\end_inset

 or PipeEventDataList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
PipeEventDataList
\end_layout

\end_inset

 when using
\end_layout

\begin_layout Verbatim
int DeviceProxy::get_events( 
\end_layout

\begin_layout Verbatim
             int event_id, 
\end_layout

\begin_layout Verbatim
             EventDataList &event_list);
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
int DeviceProxy::get_events( 
\end_layout

\begin_layout Verbatim
             int event_id, 
\end_layout

\begin_layout Verbatim
             AttrConfEventDataList &event_list);
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
int DeviceProxy::get_events( 
\end_layout

\begin_layout Verbatim
             int event_id, 
\end_layout

\begin_layout Verbatim
             DataReadyEventDataList &event_list);
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
int DeviceProxy::get_events( 
\end_layout

\begin_layout Verbatim
             int event_id, 
\end_layout

\begin_layout Verbatim
             DevIntrChangeEventDataList &event_list);
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
int DeviceProxy::get_events( 
\end_layout

\begin_layout Verbatim
             int event_id, 
\end_layout

\begin_layout Verbatim
             PipeEventDataList &event_list);
\end_layout

\begin_layout Standard
The event data lists are vectors of EventData, AttrConfEventData, DataReadyEvent
Data or PipeEventData pointers with special destructor and clean-up methods
 to ease the memory handling.
\end_layout

\begin_layout Verbatim
class EventDataList:public vector<EventData *>
\end_layout

\begin_layout Verbatim
class AttrConfEventDataList:public vector<AttrConfEventData *>
\end_layout

\begin_layout Verbatim
class DataReadyEventDataList:public vector<DataReadyEventData *>
\end_layout

\begin_layout Verbatim
class DevIntrChangeEventDataList:public vector<DevIntrChangeEventData *>
\end_layout

\begin_layout Verbatim
class PipeEventDataList:public vector<PipeEventData *>
\end_layout

\begin_layout Paragraph
Example
\end_layout

\begin_layout Standard
Here is a typical code example of a client to register and receive events.
 First, you have to define a callback
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
CallBack
\end_layout

\end_inset

 method as follows:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
class DoubleEventCallBack : public Tango::CallBack 
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
   void push_event(Tango::EventData*);
\end_layout

\begin_layout Verbatim
}; 
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
void DoubleEventCallBack::push_event(Tango::EventData *myevent)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    Tango::DevVarDoubleArray *double_value;
\end_layout

\begin_layout Verbatim
    try
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
        cout << "DoubleEventCallBack::push_event(): called attribute " 
\end_layout

\begin_layout Verbatim
             << myevent->attr_name
\end_layout

\begin_layout Verbatim
             << " event "
\end_layout

\begin_layout Verbatim
             << myevent->event 
\end_layout

\begin_layout Verbatim
             << " (err="
\end_layout

\begin_layout Verbatim
             << myevent->err
\end_layout

\begin_layout Verbatim
             << ")" << endl;
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
         if (!myevent->err)
\end_layout

\begin_layout Verbatim
         {
\end_layout

\begin_layout Verbatim
             *(myevent->attr_value) >> double_value;
\end_layout

\begin_layout Verbatim
             cout << "double value "
\end_layout

\begin_layout Verbatim
                  << (*double_value)[0]
\end_layout

\begin_layout Verbatim
                  << endl;
\end_layout

\begin_layout Verbatim
             delete double_value;
\end_layout

\begin_layout Verbatim
         }
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
    catch (...)
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
         cout << "DoubleEventCallBack::push_event(): could not extract data
 !
\backslash
n";
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Then the main code must subscribe
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
evebt-subscribe
\end_layout

\end_inset

 to the event and choose the push or the pull model for event reception.
\end_layout

\begin_layout Standard

\series bold
Push model
\series default
:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
DoubleEventCallBack *double_callback = new DoubleEventCallBack; 
\end_layout

\begin_layout Verbatim
      
\end_layout

\begin_layout Verbatim
Tango::DeviceProxy *mydevice = new Tango::DeviceProxy("my/device/1");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
int event_id;
\end_layout

\begin_layout Verbatim
const string attr_name("current");
\end_layout

\begin_layout Verbatim
event_id = mydevice->subscribe_event(attr_name, 
\end_layout

\begin_layout Verbatim
                         Tango::CHANGE_EVENT,
\end_layout

\begin_layout Verbatim
                         double_callback);
\end_layout

\begin_layout Verbatim
cout << "event_client() id = " << event_id << endl;
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
// The callback methods are executed by the Tango event reception thread.
\end_layout

\begin_layout Verbatim
// The main thread is not concerned of event reception.
\end_layout

\begin_layout Verbatim
// Whatch out with synchronisation and data access in a multi threaded environme
nt!
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
sleep(1000); // wait for events
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
mydevice->unsubscribe_event(event_id);
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard

\series bold
Pull model
\series default
:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
DoubleEventCallBack *double_callback = new DoubleEventCallBack;
\end_layout

\begin_layout Verbatim
int event_queue_size = 100; // keep the last 100 events
\end_layout

\begin_layout Verbatim
      
\end_layout

\begin_layout Verbatim
Tango::DeviceProxy *mydevice = new Tango::DeviceProxy("my/device/1");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
int event_id;
\end_layout

\begin_layout Verbatim
const string attr_name("current");
\end_layout

\begin_layout Verbatim
event_id = mydevice->subscribe_event(attr_name, 
\end_layout

\begin_layout Verbatim
                         Tango::CHANGE_EVENT,
\end_layout

\begin_layout Verbatim
                         event_queue_size);
\end_layout

\begin_layout Verbatim
cout << "event_client() id = " << event_id << endl;
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
// Check every 3 seconds whether new events have arrived and trigger the
 callback method 
\end_layout

\begin_layout Verbatim
// for the new events.
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
for (int i=0; i < 100; i++)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    sleep (3); 
\end_layout

\begin_layout Verbatim
    
\end_layout

\begin_layout Verbatim
    // Read the stored event data from the queue and call the callback method
 for every event.
\end_layout

\begin_layout Verbatim
    mydevice->get_events(event_id, double_callback);
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
event_test->unsubscribe_event(event_id);
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Section
Group
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
group
\end_layout

\end_inset


\end_layout

\begin_layout Standard
A Tango Group provides the user with a single point of control for a collection
 of devices.
 By analogy, one could see a Tango Group as a proxy for a collection of
 devices.
 For instance, the Tango Group API supplies a 
\emph on
command_inout()
\emph default
 method to execute the same command on all the elements of a group.
 
\end_layout

\begin_layout Standard
A Tango Group is also a hierarchical object.
 In other words, it is possible to build a group of both groups and individual
 devices.
 This feature allows creating logical views of the control system - each
 view representing a hierarchical family of devices or a sub-system.
 
\end_layout

\begin_layout Standard
In this chapter, we will use the term 
\emph on
hierarchy
\emph default
 to refer to a group and its sub-groups.
 The term 
\emph on
Group
\emph default
 designates to the local set of devices attached to a specific Group.
 
\end_layout

\begin_layout Subsection
Getting started with Tango group
\end_layout

\begin_layout Standard
The quickest way of getting started is to study an example\SpecialChar \ldots{}

\end_layout

\begin_layout Standard
Imagine we are vacuum engineers who need to monitor and control hundreds
 of gauges distributed over the 16 cells of a large-scale instrument.
 Each cell contains several penning and pirani gauges.
 It also contains one "strange" gauge.
 Our main requirement is to be able to control the whole set of gauges,
 a family of gauges located into a particular cell (e.g.
 all the penning gauges of the 6th cell) or a single gauge (e.g.
 the strange gauge of the 7th cell).
 Using a Tango Group, such features are quite straightforward to obtain.
 
\end_layout

\begin_layout Standard
Reading the description of the problem, the device hierarchy becomes obvious.
 Our "gauges" group will have the following structure: 
\end_layout

\begin_layout Verbatim
-> gauges
\end_layout

\begin_layout Verbatim
  |  -> cell-01
\end_layout

\begin_layout Verbatim
  |     |-> inst-c01/vac-gauge/strange 
\end_layout

\begin_layout Verbatim
  |     |-> penning 
\end_layout

\begin_layout Verbatim
  |     |   |-> inst-c01/vac-gauge/penning-01 
\end_layout

\begin_layout Verbatim
  |     |   |-> inst-c01/vac-gauge/penning-02 
\end_layout

\begin_layout Verbatim
  |     |   |- ...
 
\end_layout

\begin_layout Verbatim
  |     |   |-> inst-c01/vac-gauge/penning-xx 
\end_layout

\begin_layout Verbatim
  |     |-> pirani 
\end_layout

\begin_layout Verbatim
  |         |-> inst-c01/vac-gauge/pirani-01
\end_layout

\begin_layout Verbatim
  |         |-> ...
 
\end_layout

\begin_layout Verbatim
  |         |-> inst-c01/vac-gauge/pirani-xx 
\end_layout

\begin_layout Verbatim
  |  -> cell-02
\end_layout

\begin_layout Verbatim
  |     |-> inst-c02/vac-gauge/strange 
\end_layout

\begin_layout Verbatim
  |     |-> penning 
\end_layout

\begin_layout Verbatim
  |     |   |-> inst-c02/vac-gauge/penning-01 
\end_layout

\begin_layout Verbatim
  |     |   |-> ...
 
\end_layout

\begin_layout Verbatim
  |     | 
\end_layout

\begin_layout Verbatim
  |     |-> pirani 
\end_layout

\begin_layout Verbatim
  |     |   |-> ...
 
\end_layout

\begin_layout Verbatim
  |  -> cell-03 
\end_layout

\begin_layout Verbatim
  |     |-> ...
 
\end_layout

\begin_layout Verbatim
  |         | -> ...
 
\end_layout

\begin_layout Standard
In the C++, such a hierarchy can be build as follows (basic version): 
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- step0: create the root group 
\end_layout

\begin_layout Verbatim
Tango::Group *gauges = new Tango::Group("gauges");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step1: create a group for the n-th cell
\end_layout

\begin_layout Verbatim
Tango::Group *cell = new Tango::Group("cell-01");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step2: make the cell a sub-group of the root group 
\end_layout

\begin_layout Verbatim
gauges->add(cell);
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step3: create a "penning" group 
\end_layout

\begin_layout Verbatim
Tango::Group *gauge_family = new Tango::Group("penning");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step4: add all penning gauges located into the cell (note the wildcard)
\end_layout

\begin_layout Verbatim
gauge_family->add("inst-c01/vac-gauge/penning*");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step5: add the penning gauges to the cell
\end_layout

\begin_layout Verbatim
cell->add(gauge_family);
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step6: create a "pirani" group 
\end_layout

\begin_layout Verbatim
gauge_family = new Tango::Group("pirani");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step7: add all pirani gauges located into the cell (note the wildcard)
\end_layout

\begin_layout Verbatim
gauge_family->add("inst-c01/vac-gauge/pirani*");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step8: add the pirani gauges to the cell
\end_layout

\begin_layout Verbatim
cell->add(gauge_family);
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- step9: add the "strange" gauge to the cell
\end_layout

\begin_layout Verbatim
cell->add("inst-c01/vac-gauge/strange");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//- repeat step 1 to 9 for the remaining cells
\end_layout

\begin_layout Verbatim
cell = new Tango::Group("cell-02");
\end_layout

\begin_layout Verbatim
...
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset

 
\end_layout

\begin_layout Standard

\series bold
Important note
\series default
: There is no particular order to create the hierarchy.
 However, the insertion order of the devices is conserved throughout the
 lifecycle of the Group and cannot be changed.
 That way, the Group implementation can guarantee the order in which results
 are returned (see below).
 
\end_layout

\begin_layout Standard
Keeping a reference to the root group
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
group
\end_layout

\end_inset

 is enough to manage the whole hierarchy (i.e.
 there no need to keep trace of the sub-groups or individual devices).
 The Group interface provides methods to retrieve a sub-group or an individual
 device.
 
\end_layout

\begin_layout Standard
Be aware that a C++ group allways gets the ownership of its children and
 deletes them when it is itself deleted.
 Therefore, never try to delete a Group (respectively a DeviceProxy) returned
 by a call to 
\emph on
Tango::Group::get_group()
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
get-group
\end_layout

\end_inset

 (respectively to 
\emph on
Tango::Group::get_device()
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
get-device
\end_layout

\end_inset

).
 Use the 
\emph on
Tango::Group::remove()
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
remove
\end_layout

\end_inset

 method instead (see the Tango Group class API documentation for details).
 
\end_layout

\begin_layout Standard
We can now perform any action on any element of our "gauges" group.
 For instance, let's ping the whole hierarchy to be sure that all devices
 are alive.
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- ping the whole hierarchy 
\end_layout

\begin_layout Verbatim
if (gauges->ping() == true)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    std::cout << "all devices alive" << std::endl;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
else
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    std::cout << "at least one dead/busy/locked/...
 device" << std::endl;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset

 
\end_layout

\begin_layout Subsection
Forward or not forward
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
forward
\end_layout

\end_inset

?
\end_layout

\begin_layout Standard
Since a Tango Group is a hierarchical object, any action performed on a
 group can be forwarded to its sub-groups.
 Most of the methods in the Group interface have a so-called 
\emph on
forward
\emph default
 option controlling this propagation.
 When set to 
\emph on
false
\emph default
, the action is only performed on the local set of devices.
 Otherwise, the action is also forwarded to the sub-groups, in other words,
 propagated along the hierarchy.
 In C++ , the forward option defaults to true (thanks to the C++ default
 argument value).
 There is no such mechanism in Java and the forward option must be systematicall
y specified.
\end_layout

\begin_layout Subsection
Executing a command
\end_layout

\begin_layout Standard
As a proxy for a collection of devices, the Tango Group provides an interface
 similar to the DeviceProxy's.
 For the execution of a command, the Group
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
group
\end_layout

\end_inset

 interface contains several implementations of the 
\emph on
command_inout
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
command-inout
\end_layout

\end_inset


\emph default
 method.
 Both synchronous and asynchronous forms are supported.
 
\end_layout

\begin_layout Subsubsection
Obtaining command results
\begin_inset CommandInset label
LatexCommand label
name "sub:Obt-cmd-results"

\end_inset


\end_layout

\begin_layout Standard
Command results are returned using a Tango::GroupCmdReplyList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupCmdReplyList
\end_layout

\end_inset

.
 This is nothing but a vector containing a Tango::GroupCmdReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupCmdReply
\end_layout

\end_inset

 for each device in the group.
 The Tango::GroupCmdReply contains the actual data (i.e.
 the Tango::DeviceData).
 By inheritance, it may also contain any error occurred during the execution
 of the command (in which case the data is invalid).
 
\end_layout

\begin_layout Standard
We previously indicated that the Tango Group implementation guarantees that
 the command results are returned in the order in which its elements were
 attached to the group.
 For instance, if g1 is a group containing three devices attached in the
 following order:
\end_layout

\begin_layout Verbatim
g1->add("my/device/01");
\end_layout

\begin_layout Verbatim
g1->add("my/device/03");
\end_layout

\begin_layout Verbatim
g1->add("my/device/02");
\end_layout

\begin_layout Standard
the results of 
\end_layout

\begin_layout Verbatim
Tango::GroupCmdReplyList crl = g1->command_inout("Status");
\end_layout

\begin_layout Standard
will be organized as follows:
\end_layout

\begin_layout Standard

\emph on
crl[0]
\emph default
 contains the status of my/device/01 
\begin_inset Newline newline
\end_inset


\emph on
crl[1]
\emph default
 contains the status of my/device/03 
\begin_inset Newline newline
\end_inset


\emph on
crl[2]
\emph default
 contains the status of my/device/02
\end_layout

\begin_layout Standard
Things get more complicated if sub-groups are added "between" devices.
\end_layout

\begin_layout Verbatim
g2->add("my/device/04");
\end_layout

\begin_layout Verbatim
g2->add("my/device/05");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
g4->add("my/device/08");
\end_layout

\begin_layout Verbatim
g4->add("my/device/09");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
g3->add("my/device/06");
\end_layout

\begin_layout Verbatim
g3->add(g4);
\end_layout

\begin_layout Verbatim
g3->add("my/device/07");
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
g1->add("my/device/01");
\end_layout

\begin_layout Verbatim
g1->add(g2);
\end_layout

\begin_layout Verbatim
g1->add("my/device/03");
\end_layout

\begin_layout Verbatim
g1->add(g3);
\end_layout

\begin_layout Verbatim
g1->add("my/device/02");
\end_layout

\begin_layout Standard
The result order in the Tango::GroupCmdReplyList depends on the value of
 the forward
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
forward
\end_layout

\end_inset

 option.
 If set to 
\emph on
true
\emph default
, the results will be organized as follows:
\end_layout

\begin_layout Verbatim
Tango::GroupCmdReplyList crl = g1->command_inout("Status", true);
\end_layout

\begin_layout Standard

\emph on
crl[0]
\emph default
 contains the status of my/device/01 which belongs to g1
\begin_inset Newline newline
\end_inset


\emph on
crl[1]
\emph default
 contains the status of my/device/04 which belongs to g1.g2
\begin_inset Newline newline
\end_inset


\emph on
crl[2]
\emph default
 contains the status of my/device/05 which belongs to g1.g2
\begin_inset Newline newline
\end_inset


\emph on
crl[3]
\emph default
 contains the status of my/device/03 which belongs to g1
\begin_inset Newline newline
\end_inset


\emph on
crl[4]
\emph default
 contains the status of my/device/06 which belongs to g1.g3
\begin_inset Newline newline
\end_inset


\emph on
crl[5]
\emph default
 contains the status of my/device/08 which belongs to g1.g3.g4
\begin_inset Newline newline
\end_inset


\emph on
crl[6]
\emph default
 contains the status of my/device/09 which belongs to g1.g3.g 
\begin_inset Newline newline
\end_inset


\emph on
crl[7]
\emph default
 contains the status of my/device/07 which belongs to g1.g3
\begin_inset Newline newline
\end_inset


\emph on
crl[8]
\emph default
 contains the status of my/device/02 which belongs to g1 
\end_layout

\begin_layout Standard
If the forward option is set to 
\emph on
false
\emph default
, the results are:
\end_layout

\begin_layout Verbatim
Tango::GroupCmdReplyList crl = g1->command_inout("Status", false); 
\end_layout

\begin_layout Standard

\emph on
crl[0]
\emph default
 contains the status of my/device/01 which belongs to g 
\begin_inset Newline newline
\end_inset


\emph on
crl[1]
\emph default
 contains the status of my/device/03 which belongs to g1
\begin_inset Newline newline
\end_inset


\emph on
crl[2]
\emph default
 contains the status of my/device/02 which belongs to g1
\end_layout

\begin_layout Standard
The Tango::GroupCmdReply contains some public members allowing the identificatio
n of both the device (Tango::GroupCmdReply::dev_name
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
dev-name
\end_layout

\end_inset

) and the command (Tango::GroupCmdReply::obj_name
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
obj-name
\end_layout

\end_inset

).
 It means that, depending of your application, you can associate a response
 with its source using its position in the response list or using the Tango::Gro
upCmdReply::dev_name member.
\end_layout

\begin_layout Subsubsection
Case 1: a command, no argument
\begin_inset CommandInset label
LatexCommand label
name "sub:Case-1"

\end_inset


\end_layout

\begin_layout Standard
As an example, we execute the Status command on the whole hierarchy synchronousl
y.
\end_layout

\begin_layout Verbatim
Tango::GroupCmdReplyList crl = gauges->command_inout("Status");
\end_layout

\begin_layout Standard
As a first step in the results processing, it could be interesting to check
 value returned by the 
\emph on
has_failed
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
has-failed
\end_layout

\end_inset

()
\emph default
 method of the GroupCmdReplyList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupCmdReplyList
\end_layout

\end_inset

.
 If it is set to true, it means that at least one error occurred during
 the execution of the command (i.e.
 at least one device gave error).
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
if (crl.has_failed())
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    cout << "at least one error occurred" << endl;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
else
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    cout << "no error " << endl;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Now, we have to process each "individual response" in the list.
 
\end_layout

\begin_layout Subsubsection
A few words on error handling and data extraction
\end_layout

\begin_layout Standard
Depending of the application and/or the developer's programming habits,
 each individual error can be handle by the C++ (or Java) exception
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
exception
\end_layout

\end_inset

 mechanism or using the dedicated 
\emph on
has_failed
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
has-failed
\end_layout

\end_inset

()
\emph default
 method.
 The GroupReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupReply
\end_layout

\end_inset

 class - which is the mother class of both GroupCmdReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupCmdReply
\end_layout

\end_inset

 and GroupAttrReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupAttrReply
\end_layout

\end_inset

 - contains a static method to enable (or disable) exceptions called 
\emph on
enable_exception()
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
enable-exception()
\end_layout

\end_inset

.
 By default, exceptions are disabled.
 The following example is proposed with both exceptions enable and disable.
 
\end_layout

\begin_layout Standard
In C++, data can be extracted directly from an individual reply.
 The GroupCmdReply interface contains a template operator >> allowing the
 extraction of any supported Tango type (in fact the actual data extraction
 is delegated to DeviceData::operator >>).
 One dedicated extract method is also provided in order to extract DevVarLongStr
ingArray and DevVarDoubleStringArray types to std::vectors.
\end_layout

\begin_layout Standard
Error and data handling C++ example:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//-------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- synch.
 group command example with exception enabled
\end_layout

\begin_layout Verbatim
//-------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- enable exceptions and save current mode
\end_layout

\begin_layout Verbatim
bool last_mode = GroupReply::enable_exception(true);
\end_layout

\begin_layout Verbatim
//- process each response in the list ...
\end_layout

\begin_layout Verbatim
for (int r = 0; r < crl.size(); r++)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- enter a try/catch block
\end_layout

\begin_layout Verbatim
   try
\end_layout

\begin_layout Verbatim
   {
\end_layout

\begin_layout Verbatim
//- try to extract the data from the r-th reply
\end_layout

\begin_layout Verbatim
//- suppose data contains a double
\end_layout

\begin_layout Verbatim
       double ans;
\end_layout

\begin_layout Verbatim
       crl[r] >> ans;
\end_layout

\begin_layout Verbatim
       cout << crl[r].dev_name()
\end_layout

\begin_layout Verbatim
            << "::"
\end_layout

\begin_layout Verbatim
            << crl[r].obj_name()
\end_layout

\begin_layout Verbatim
            << " returned "
\end_layout

\begin_layout Verbatim
            << ans
\end_layout

\begin_layout Verbatim
            << endl;
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
    catch (const DevFailed& df)
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- DevFailed caught while trying to extract the data from reply
\end_layout

\begin_layout Verbatim
      for (int err = 0; err < df.errors.length(); err++)
\end_layout

\begin_layout Verbatim
      {
\end_layout

\begin_layout Verbatim
           cout << "error: " << df.errors[err].desc.in() << endl;
\end_layout

\begin_layout Verbatim
      }
\end_layout

\begin_layout Verbatim
//- alternatively, one can use crl[r].get_err_stack() see below
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
    catch (...)
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
       cout << "unknown exception caught";
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
//- restore last exception mode (if needed)
\end_layout

\begin_layout Verbatim
GroupReply::enable_exception(last_mode);
\end_layout

\begin_layout Verbatim
//- Clear the response list (if reused later in the code)
\end_layout

\begin_layout Verbatim
crl.reset();
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim

\end_layout

\begin_layout Verbatim
//-------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- synch.
 group command example with exception disabled
\end_layout

\begin_layout Verbatim
//-------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- disable exceptions and save current mode bool
\end_layout

\begin_layout Verbatim
last_mode = GroupReply::enable_exception(false);
\end_layout

\begin_layout Verbatim
//- process each response in the list ...
\end_layout

\begin_layout Verbatim
for (int r = 0; r < crl.size(); r++)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- did the r-th device give error?
\end_layout

\begin_layout Verbatim
    if (crl[r].has_failed() == true)
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- printout error description
\end_layout

\begin_layout Verbatim
       cout << "an error occurred while executing "
\end_layout

\begin_layout Verbatim
            << crl[r].obj_name()
\end_layout

\begin_layout Verbatim
            << " on " 
\end_layout

\begin_layout Verbatim
            << crl[r].dev_name() << endl;
\end_layout

\begin_layout Verbatim
//- dump error stack
\end_layout

\begin_layout Verbatim
       const DevErrorList& el = crl[r].get_err_stack();
\end_layout

\begin_layout Verbatim
       for (int err = 0; err < el.size(); err++)
\end_layout

\begin_layout Verbatim
       {
\end_layout

\begin_layout Verbatim
           cout << el[err].desc.in();
\end_layout

\begin_layout Verbatim
       }
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
    else
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- no error (suppose data contains a double)
\end_layout

\begin_layout Verbatim
       double ans;
\end_layout

\begin_layout Verbatim
       bool result = crl[r] >> ans;
\end_layout

\begin_layout Verbatim
       if (result == false)
\end_layout

\begin_layout Verbatim
       {
\end_layout

\begin_layout Verbatim
           cout << "could not extract double from "
\end_layout

\begin_layout Verbatim
                << crl[r].dev_name()
\end_layout

\begin_layout Verbatim
                << " reply"
\end_layout

\begin_layout Verbatim
                << endl;
\end_layout

\begin_layout Verbatim
       }
\end_layout

\begin_layout Verbatim
       else
\end_layout

\begin_layout Verbatim
       {
\end_layout

\begin_layout Verbatim
           cout << crl[r].dev_name()
\end_layout

\begin_layout Verbatim
                << "::"
\end_layout

\begin_layout Verbatim
                << crl[r].obj_name()
\end_layout

\begin_layout Verbatim
                << " returned "
\end_layout

\begin_layout Verbatim
                << ans
\end_layout

\begin_layout Verbatim
                << endl;
\end_layout

\begin_layout Verbatim
       }
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
//- restore last exception mode (if needed)
\end_layout

\begin_layout Verbatim
GroupReply::enable_exception(last_mode);
\end_layout

\begin_layout Verbatim
//- Clear the response list (if reused later in the code)
\end_layout

\begin_layout Verbatim
crl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Now execute the same command asynchronously.
 C++ example:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//-------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- asynch.
 group command example (C++ example)
\end_layout

\begin_layout Verbatim
//-------------------------------------------------------
\end_layout

\begin_layout Verbatim
long request_id = gauges->command_inout_asynch("Status");
\end_layout

\begin_layout Verbatim
//- do some work
\end_layout

\begin_layout Verbatim
do_some_work();
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
//- get results
\end_layout

\begin_layout Verbatim
crl = gauges->command_inout_reply(request_id);
\end_layout

\begin_layout Verbatim
//- process responses as previously describe in the synch.
 implementation
\end_layout

\begin_layout Verbatim
for (int r = 0; r < crl.size(); r++)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- data processing and error handling goes here
\end_layout

\begin_layout Verbatim
//- copy/paste code from previous example
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
//- clear the response list (if reused later in the code)
\end_layout

\begin_layout Verbatim
crl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Subsubsection
Case 2: a command, one argument
\begin_inset CommandInset label
LatexCommand label
name "sub:Case-2"

\end_inset

 
\end_layout

\begin_layout Standard
Here, we give an example in which the same input argument is applied to
 all devices in the group (or its sub-groups).
 
\end_layout

\begin_layout Standard
In C++:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- the argument value
\end_layout

\begin_layout Verbatim
double d = 0.1;
\end_layout

\begin_layout Verbatim
//- insert it into the TANGO generic container for command: DeviceData
\end_layout

\begin_layout Verbatim
Tango::DeviceData dd;
\end_layout

\begin_layout Verbatim
dd << d;
\end_layout

\begin_layout Verbatim
//- execute the command: Dev_Void SetDummyFactor (Dev_Double)
\end_layout

\begin_layout Verbatim
Tango::GroupCmdReplyList crl = gauges->command_inout("SetDummyFactor", dd);
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Since the SetDummyFactor command does not return any value, the individual
 replies (i.e.
 the GroupCmdReply) do not contain any data.
 However, we have to check their 
\emph on
has_failed
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
has-failed
\end_layout

\end_inset

()
\emph default
 method returned value to be sure that the command completed successfully
 on each device (acknowledgement).
 Note that in such a case, exceptions are useless since we never try to
 extract data from the replies.
 
\end_layout

\begin_layout Standard
In C++ we should have something like: 
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- no need to process the results if no error occurred (Dev_Void command)
\end_layout

\begin_layout Verbatim
if (crl.has_failed())
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- at least one error occurred
\end_layout

\begin_layout Verbatim
    for (int r = 0; r < crl.size(); r++)
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- handle errors here (see previous C++ examples)
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
//- clear the response list (if reused later in the code)
\end_layout

\begin_layout Verbatim
crl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
See case 1 for an example of asynchronous command.
\end_layout

\begin_layout Subsubsection
Case 3: a command, several arguments
\begin_inset CommandInset label
LatexCommand label
name "sub:Case-3"

\end_inset


\end_layout

\begin_layout Standard
Here, we give an example in which a 
\series bold
specific
\series default
 input argument is applied to each device in the hierarchy.
 In order to use this form of command_inout
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
command-inout
\end_layout

\end_inset

, the user must have an "a priori" and "perfect" knowledge of the devices
 order in the hierarchy.
 In such a case, command arguments are passed in an "array" (with one entry
 for each device in the hierarchy).
\end_layout

\begin_layout Standard
The C++ implementation provides a template method which accepts a std::vector
 of "C++ type for command argument".
 This allows passing any kind of data using a single method.
\end_layout

\begin_layout Standard
The size of this vector must equal the number of device in the hierarchy
 (respectively the number of device in the group) if the forward
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
forward
\end_layout

\end_inset

 option is set to true (respectively set to false).
 Otherwise, an exception
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
exception
\end_layout

\end_inset

 is thrown.
\end_layout

\begin_layout Standard
The first item in the vector is applied to the first device in the hierarchy,
 the second to the second device in the hierarchy, and so on\SpecialChar \ldots{}
That's why the
 user must have a "perfect" knowledge of the devices order in the hierarchy.
 
\end_layout

\begin_layout Standard
Assuming that gauges are ordered by name, the SetDummyFactor command can
 be executed on group "cell-01" (and its sub-groups) as follows:
\end_layout

\begin_layout Standard
Remember, "cell-01" has the following internal structure: 
\end_layout

\begin_layout Verbatim
-> gauges
\end_layout

\begin_layout Verbatim
   | -> cell-01
\end_layout

\begin_layout Verbatim
   |    |-> inst-c01/vac-gauge/strange
\end_layout

\begin_layout Verbatim
   |    |-> penning
\end_layout

\begin_layout Verbatim
   |    |   |-> inst-c01/vac-gauge/penning-01
\end_layout

\begin_layout Verbatim
   |    |   |-> inst-c01/vac-gauge/penning-02
\end_layout

\begin_layout Verbatim
   |    |   |-> ...
\end_layout

\begin_layout Verbatim
   |    |   |-> inst-c01/vac-gauge/penning-xx
\end_layout

\begin_layout Verbatim
   |    |-> pirani
\end_layout

\begin_layout Verbatim
   |        |-> inst-c01/vac-gauge/pirani-01
\end_layout

\begin_layout Verbatim
   |        |-> ...
\end_layout

\begin_layout Verbatim
   |        |-> inst-c01/vac-gauge/pirani-xx
\end_layout

\begin_layout Standard
Passing a specific argument to each device in C++:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- get a reference to the target group
\end_layout

\begin_layout Verbatim
Tango::Group *g = gauges->get_group("cell-01");
\end_layout

\begin_layout Verbatim
//- get number of device in the hierarchy (starting at cell-01)
\end_layout

\begin_layout Verbatim
long n_dev = g->get_size(true);
\end_layout

\begin_layout Verbatim
//- Build argin list
\end_layout

\begin_layout Verbatim
std::vector<double> argins(n_dev);
\end_layout

\begin_layout Verbatim
//- argument for inst-c01/vac-gauge/strange
\end_layout

\begin_layout Verbatim
argins[0] = 0.0;
\end_layout

\begin_layout Verbatim
//- argument for inst-c01/vac-gauge/penning-01
\end_layout

\begin_layout Verbatim
argins[1] = 0.1;
\end_layout

\begin_layout Verbatim
//- argument for inst-c01/vac-gauge/penning-02
\end_layout

\begin_layout Verbatim
argins[2] = 0.2;
\end_layout

\begin_layout Verbatim
//- argument for remaining devices in cell-01.penning
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
//- argument for devices in cell-01.pirani
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
//- the reply list
\end_layout

\begin_layout Verbatim
Tango::GroupCmdReplyList crl;
\end_layout

\begin_layout Verbatim
//- enter a try/catch block (see below)
\end_layout

\begin_layout Verbatim
try
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- execute the command
\end_layout

\begin_layout Verbatim
    crl = g->command_inout("SetDummyFactor", argins, true);
\end_layout

\begin_layout Verbatim
    if (crl.has_failed())
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- error handling goes here (see case 1)
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
catch (const DevFailed& df)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- see below
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
crl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
If we want to execute the command locally on "cell-01" (i.e.
 not on its sub-groups), we should write the following C++ code:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- get a reference to the target group
\end_layout

\begin_layout Verbatim
Tango::Group *g = gauges->get_group("cell-01");
\end_layout

\begin_layout Verbatim
//- get number of device in the group (starting at cell-01)
\end_layout

\begin_layout Verbatim
long n_dev = g->get_size(false);
\end_layout

\begin_layout Verbatim
//- Build argin list
\end_layout

\begin_layout Verbatim
std::vector<double> argins(n_dev);
\end_layout

\begin_layout Verbatim
//- argins for inst-c01/vac-gauge/penning-01
\end_layout

\begin_layout Verbatim
argins[0] = 0.1;
\end_layout

\begin_layout Verbatim
//- argins for inst-c01/vac-gauge/penning-02
\end_layout

\begin_layout Verbatim
argins[1] = 0.2;
\end_layout

\begin_layout Verbatim
//- argins for remaining devices in cell-01.penning
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
//- the reply list
\end_layout

\begin_layout Verbatim
Tango::GroupCmdReplyList crl;
\end_layout

\begin_layout Verbatim
//- enter a try/catch block (see below)
\end_layout

\begin_layout Verbatim
try
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- execute the command
\end_layout

\begin_layout Verbatim
    crl = g->command_inout("SetDummyFactor", argins, false);
\end_layout

\begin_layout Verbatim
    if (crl.has_failed())
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- error handling goes here (see case 1)
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
catch (const DevFailed& df)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- see below
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
crl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Note: if we want to execute the command locally on "cell-01" (i.e.
 not on its sub-groups), we should write the following code:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- get a reference to the target group
\end_layout

\begin_layout Verbatim
Group g = gauges.get_group("cell-01");
\end_layout

\begin_layout Verbatim
//- get pre-build arguments list for the group (starting@cell-01)
\end_layout

\begin_layout Verbatim
DeviceData[] argins = g.get_command_specific_argument_list(false);
\end_layout

\begin_layout Verbatim
//- argins for inst-c01/vac-gauge/penning-01
\end_layout

\begin_layout Verbatim
argins[0].insert(0.1);
\end_layout

\begin_layout Verbatim
//- argins for inst-c01/vac-gauge/penning-02
\end_layout

\begin_layout Verbatim
argins[1].insert(0.2);
\end_layout

\begin_layout Verbatim
//- argins for remaining devices in cell-01.penning
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
//- the reply list 
\end_layout

\begin_layout Verbatim
GroupCmdReplyList crl;
\end_layout

\begin_layout Verbatim
//- enter a try/catch block (see below)
\end_layout

\begin_layout Verbatim
try
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- execute the command
\end_layout

\begin_layout Verbatim
    crl = g.command_inout("SetDummyFactor", argins, false, false);
\end_layout

\begin_layout Verbatim
    if (crl.has_failed())
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- error handling goes here (see case 1)
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
catch (DevFailed d)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- see below
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
This form of 
\emph on
command_inout
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
command-inout
\end_layout

\end_inset


\emph default
 (the one that accepts an array of value as its input argument), may throw
 an exception
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
exception
\end_layout

\end_inset

 
\series bold
before
\series default
 executing the command if the number of elements in the input array does
 not match the number of individual devices in the group
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
group
\end_layout

\end_inset

 or in the hierarchy (depending on the forward option).
 
\end_layout

\begin_layout Standard
An asynchronous version of this method is also available.
 See case 1 for an example of asynchronous command.
\end_layout

\begin_layout Subsection
Reading attribute(s)
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
attribute
\end_layout

\end_inset


\begin_inset CommandInset label
LatexCommand label
name "sub:Read-attr"

\end_inset

 
\end_layout

\begin_layout Standard
In order to read attribute(s), the Group
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
group
\end_layout

\end_inset

 interface contains several implementations of the 
\emph on
read_attribute()
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
read-attribute
\end_layout

\end_inset

 and 
\emph on
read_attributes()
\emph default
 methods.
 Both synchronous and asynchronous forms are supported.
 Reading several attributes is very similar to reading a single attribute.
 Simply replace the std::string used for attribute name by a vector of std::stri
ng with one element for each attribute name.
 In case of read_attributes() call, the order of attribute value returned
 in the GroupAttrReplyList is all attributes for first element in the group
 followed by all attributes for the second group element and so on.
\end_layout

\begin_layout Subsubsection
Obtaining attribute values
\begin_inset CommandInset label
LatexCommand label
name "sub:O-attr-values"

\end_inset


\end_layout

\begin_layout Standard
Attribute values are returned using a GroupAttrReplyList
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupAttrReplyList
\end_layout

\end_inset

.
 This is nothing but an array containing a GroupAttrReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupAttrReply
\end_layout

\end_inset

 for each device in the group.
 The GroupAttrReply contains the actual data (i.e.
 the DeviceAttribute).
 By inheritance, it may also contain any error occurred during the execution
 of the command (in which case the data is invalid).
 
\end_layout

\begin_layout Standard
Here again, the Tango Group implementation guarantees that the attribute
 values are returned in the order in which its elements were attached to
 the group.
 See Obtaining command results for details.
\end_layout

\begin_layout Standard
The GroupAttrReply contains some public methods allowing the identification
 of both the device (GroupAttrReply::dev_name
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
dev-name
\end_layout

\end_inset

) and the attribute (GroupAttrReply::obj_name
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
obj-name
\end_layout

\end_inset

).
 It means that, depending of your application, you can associate a response
 with its source using its position in the response list or using the Tango::Gro
upAttrReply::dev_name member.
\end_layout

\begin_layout Subsubsection
A few words on error handling and data extraction
\end_layout

\begin_layout Standard
Here again, depending of the application and/or the developer's programming
 habits, each individual error can be handle by the C++ exception
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
exception
\end_layout

\end_inset

 mechanism or using the dedicated 
\emph on
has_failed
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
has-failed
\end_layout

\end_inset


\emph on
()
\emph default
 method.
 The GroupReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupReply
\end_layout

\end_inset

 class - which is the mother class of both GroupCmdReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupCmdReply
\end_layout

\end_inset

 and GroupAttrReply
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
GroupAttrReply
\end_layout

\end_inset

 - contains a static method to enable (or disable) exceptions called 
\emph on
enable_exception()
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
enable-exception()
\end_layout

\end_inset

.
 By default, exceptions are disabled.
 The following example is proposed with both exceptions enable and disable.
 
\end_layout

\begin_layout Standard
In C++, data can be extracted directly from an individual reply.
 The GroupAttrReply interface contains a template operator>> allowing the
 extraction of any supported Tango type (in fact the actual data extraction
 is delegated to DeviceAttribute::operator>>).
 
\end_layout

\begin_layout Standard
Reading an attribute is very similar to executing a command.
 
\end_layout

\begin_layout Standard
Reading an attribute in C++:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//-----------------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- synch.
 read "vacuum" attribute on each device in the hierarchy
\end_layout

\begin_layout Verbatim
//- with exceptions enabled - C++ example
\end_layout

\begin_layout Verbatim
//-----------------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- enable exceptions and save current mode
\end_layout

\begin_layout Verbatim
bool last_mode = GroupReply::enable_exception(true);
\end_layout

\begin_layout Verbatim
//- read attribute
\end_layout

\begin_layout Verbatim
Tango::GroupAttrReplyList arl = gauges->read_attribute("vacuum");
\end_layout

\begin_layout Verbatim
//- for each response in the list ...
\end_layout

\begin_layout Verbatim
for (int r = 0; r < arl.size(); r++)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- enter a try/catch block
\end_layout

\begin_layout Verbatim
   try
\end_layout

\begin_layout Verbatim
   {
\end_layout

\begin_layout Verbatim
//- try to extract the data from the r-th reply
\end_layout

\begin_layout Verbatim
//- suppose data contains a double
\end_layout

\begin_layout Verbatim
      double ans;
\end_layout

\begin_layout Verbatim
      arl[r] >> ans;
\end_layout

\begin_layout Verbatim
      cout << arl[r].dev_name()
\end_layout

\begin_layout Verbatim
           << "::"
\end_layout

\begin_layout Verbatim
           << arl[r].obj_name()
\end_layout

\begin_layout Verbatim
           << " value is "
\end_layout

\begin_layout Verbatim
           << ans << endl;
\end_layout

\begin_layout Verbatim
   }
\end_layout

\begin_layout Verbatim
   catch (const DevFailed& df)
\end_layout

\begin_layout Verbatim
   {
\end_layout

\begin_layout Verbatim
//- DevFailed caught while trying to extract the data from reply
\end_layout

\begin_layout Verbatim
      for (int err = 0; err < df.errors.length(); err++)
\end_layout

\begin_layout Verbatim
      {
\end_layout

\begin_layout Verbatim
         cout << "error: " << df.errors[err].desc.in() << endl;
\end_layout

\begin_layout Verbatim
      }
\end_layout

\begin_layout Verbatim
//- alternatively, one can use arl[r].get_err_stack() see below
\end_layout

\begin_layout Verbatim
   }
\end_layout

\begin_layout Verbatim
   catch (...)
\end_layout

\begin_layout Verbatim
   {
\end_layout

\begin_layout Verbatim
      cout << "unknown exception caught";
\end_layout

\begin_layout Verbatim
   }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
//- restore last exception mode (if needed)
\end_layout

\begin_layout Verbatim
GroupReply::enable_exception(last_mode);
\end_layout

\begin_layout Verbatim
//- clear the reply list (if reused later in the code)
\end_layout

\begin_layout Verbatim
arl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
In C++, an asynchronous version of the previous example could be:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- read the attribute asynchronously
\end_layout

\begin_layout Verbatim
long request_id = gauges->read_attribute_asynch("vacuum");
\end_layout

\begin_layout Verbatim
//- do some work
\end_layout

\begin_layout Verbatim
do_some_work();
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
//- get results
\end_layout

\begin_layout Verbatim
Tango::GroupAttrReplyList arl = gauges->read_attribute_reply(request_id);
\end_layout

\begin_layout Verbatim
//- process replies as previously described in the synch.
 implementation
\end_layout

\begin_layout Verbatim
for (int r = 0; r < arl.size(); r++)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- data processing and/or error handling goes here
\end_layout

\begin_layout Verbatim
...
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
//- clear the reply list (if reused later in the code)
\end_layout

\begin_layout Verbatim
arl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Subsection
Writing an attribute
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
attribute
\end_layout

\end_inset

 
\end_layout

\begin_layout Standard
The Group interface contains several implementations of the 
\emph on
write_attribute()
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
write-attribute
\end_layout

\end_inset

 method.
 Both synchronous and asynchronous forms are supported.
 However, writing more than one attribute at a time is not supported.
\end_layout

\begin_layout Subsubsection
Obtaining acknowledgement
\begin_inset CommandInset label
LatexCommand label
name "sub:O-ack"

\end_inset


\end_layout

\begin_layout Standard
Acknowledgements are returned using a GroupReplyList.
 This is nothing but an array containing a GroupReply for each device in
 the group.
 The GroupReply may contain any error occurred during the execution of the
 command.
 The return value of the 
\emph on
has_failed
\emph default

\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
has-failed
\end_layout

\end_inset


\emph on
()
\emph default
 method indicates whether an error occurred or not.
 If this flag is set to true, the 
\emph on
GroupReply::get_err_stack()
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
get-err-stack
\end_layout

\end_inset


\emph default
 method gives error details.
 
\end_layout

\begin_layout Standard
Here again, the Tango Group
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
group
\end_layout

\end_inset

 implementation guarantees that the attribute values are returned in the
 order in which its elements were attached to the group.
 See Obtaining command results for details.
\end_layout

\begin_layout Standard
The GroupReply contains some public members allowing the identification
 of both the device (GroupReply::dev_name
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
dev-name
\end_layout

\end_inset

) and the attribute (GroupReply::obj_name
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
obj-name
\end_layout

\end_inset

).
 It means that, depending of your application, you can associate a response
 with its source using its position in the response list or using the GroupReply
::dev_name member.
\end_layout

\begin_layout Subsubsection
Case 1: one value for all devices
\begin_inset CommandInset label
LatexCommand label
name "sub:Case-1-writing"

\end_inset

 
\end_layout

\begin_layout Standard
Here, we give an example in which the same attribute value is written on
 all devices in the group (or its sub-groups).
 Exceptions are supposed to be disabled.
\end_layout

\begin_layout Standard
Writing an attribute in C++:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//-----------------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- synch.
 write "dummy" attribute on each device in the hierarchy
\end_layout

\begin_layout Verbatim
//-----------------------------------------------------------------
\end_layout

\begin_layout Verbatim
//- assume each device support a "dummy" writable attribute
\end_layout

\begin_layout Verbatim
//- insert the value to be written into a generic container
\end_layout

\begin_layout Verbatim
Tango::DeviceAttribute value(std::string("dummy"), 3.14159);
\end_layout

\begin_layout Verbatim
//- write the attribute
\end_layout

\begin_layout Verbatim
Tango::GroupReplyList rl = gauges->write_attribute(value);
\end_layout

\begin_layout Verbatim
//- any error?
\end_layout

\begin_layout Verbatim
if (rl.has_failed() == false)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    cout << "no error" << endl;
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
else
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
    cout << "at least one error occurred" << endl;
\end_layout

\begin_layout Verbatim
//- for each response in the list ...
\end_layout

\begin_layout Verbatim
    for (int r = 0; r < rl.size(); r++)
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- did the r-th device give error?
\end_layout

\begin_layout Verbatim
       if (rl[r].has_failed() == true)
\end_layout

\begin_layout Verbatim
       {
\end_layout

\begin_layout Verbatim
//- printout error description
\end_layout

\begin_layout Verbatim
           cout << "an error occurred while reading " 
\end_layout

\begin_layout Verbatim
                << rl[r].obj_name()
\end_layout

\begin_layout Verbatim
                << " on "
\end_layout

\begin_layout Verbatim
                << rl[r].dev_name()
\end_layout

\begin_layout Verbatim
                << endl;
\end_layout

\begin_layout Verbatim
//- dump error stack
\end_layout

\begin_layout Verbatim
           const DevErrorList& el = rl[r].get_err_stack();
\end_layout

\begin_layout Verbatim
           for (int err = 0; err < el.size(); err++)
\end_layout

\begin_layout Verbatim
           {
\end_layout

\begin_layout Verbatim
              cout << el[err].desc.in();
\end_layout

\begin_layout Verbatim
           }
\end_layout

\begin_layout Verbatim
        }
\end_layout

\begin_layout Verbatim
     }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
//- clear the reply list (if reused later in the code)
\end_layout

\begin_layout Verbatim
rl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Here is a C++ asynchronous version:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- insert the value to be written into a generic container
\end_layout

\begin_layout Verbatim
Tango::DeviceAttribute value(std::string("dummy"), 3.14159);
\end_layout

\begin_layout Verbatim
//- write the attribute asynchronously
\end_layout

\begin_layout Verbatim
long request_id = gauges.write_attribute_asynch(value);
\end_layout

\begin_layout Verbatim
//- do some work
\end_layout

\begin_layout Verbatim
do_some_work();
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
 
\end_layout

\begin_layout Verbatim
//- get results
\end_layout

\begin_layout Verbatim
Tango::GroupReplyList rl = gauges->write_attribute_reply(request_id);
\end_layout

\begin_layout Verbatim
//- process replies as previously describe in the synch.
 implementation ...
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Subsubsection
Case 2: a specific value per device
\begin_inset CommandInset label
LatexCommand label
name "sub:Case-2-writing"

\end_inset


\end_layout

\begin_layout Standard
Here, we give an example in which a 
\series bold
specific
\series default
 attribute value is applied to each device in the hierarchy.
 In order to use this form of 
\emph on
write_attribute()
\emph default
, the user must have an "a priori" and "perfect" knowledge of the devices
 order in the hierarchy.
 
\end_layout

\begin_layout Standard
The C++ implementation provides a template method which accepts a std::vector
 of "C++ type for command argument".
 This allows passing any kind of data using a single method.
\end_layout

\begin_layout Standard
The size of this vector must equal the number of device in the hierarchy
 (respectively the number of device in the group) if the forward
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
forward
\end_layout

\end_inset

 option is set to true (respectively set to false).
 Otherwise, an exception
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
exception
\end_layout

\end_inset

 is thrown.
\end_layout

\begin_layout Standard
The first item in the vector is applied to the first device in the group,
 the second to the second device in the group, and so on\SpecialChar \ldots{}
That's why the user
 must have a "perfect" knowledge of the devices order in the group.
 
\end_layout

\begin_layout Standard
Assuming that gauges are ordered by name, the dummy attribute can be written
 as follows on group "cell-01" (and its sub-groups) as follows:
\end_layout

\begin_layout Standard
Remember, "cell-01" has the following internal structure: 
\end_layout

\begin_layout Verbatim
-> gauges 
\end_layout

\begin_layout Verbatim
    | -> cell-01
\end_layout

\begin_layout Verbatim
    |     |-> inst-c01/vac-gauge/strange
\end_layout

\begin_layout Verbatim
    |     |-> penning
\end_layout

\begin_layout Verbatim
    |     |    |-> inst-c01/vac-gauge/penning-01
\end_layout

\begin_layout Verbatim
    |     |    |-> inst-c01/vac-gauge/penning-02
\end_layout

\begin_layout Verbatim
    |     |    |-> ...
\end_layout

\begin_layout Verbatim
    |     |    |-> inst-c01/vac-gauge/penning-xx
\end_layout

\begin_layout Verbatim
    |     |-> pirani
\end_layout

\begin_layout Verbatim
    |          |-> inst-c01/vac-gauge/pirani-01
\end_layout

\begin_layout Verbatim
    |          |-> ...
\end_layout

\begin_layout Verbatim
    |          |-> inst-c01/vac-gauge/pirani-xx
\end_layout

\begin_layout Standard
C++ version:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- get a reference to the target group
\end_layout

\begin_layout Verbatim
Tango::Group *g = gauges->get_group("cell-01");
\end_layout

\begin_layout Verbatim
//- get number of device in the hierarchy (starting at cell-01)
\end_layout

\begin_layout Verbatim
long n_dev = g->get_size(true);
\end_layout

\begin_layout Verbatim
//- Build value list
\end_layout

\begin_layout Verbatim
std::vector<double> values(n_dev);
\end_layout

\begin_layout Verbatim
//- value for inst-c01/vac-gauge/strange
\end_layout

\begin_layout Verbatim
values[0] = 3.14159;
\end_layout

\begin_layout Verbatim
//- value for inst-c01/vac-gauge/penning-01
\end_layout

\begin_layout Verbatim
values[1] = 2 * 3.14159;
\end_layout

\begin_layout Verbatim
//- value for inst-c01/vac-gauge/penning-02
\end_layout

\begin_layout Verbatim
values[2] = 3 * 3.14159;
\end_layout

\begin_layout Verbatim
//- value for remaining devices in cell-01.penning
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
//- value for devices in cell-01.pirani
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
//- the reply list
\end_layout

\begin_layout Verbatim
Tango::GroupReplyList rl;
\end_layout

\begin_layout Verbatim
//- enter a try/catch block (see below)
\end_layout

\begin_layout Verbatim
try
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- write the "dummy" attribute
\end_layout

\begin_layout Verbatim
    rl = g->write_attribute("dummy", values, true);
\end_layout

\begin_layout Verbatim
    if (rl.has_failed())
\end_layout

\begin_layout Verbatim
    {
\end_layout

\begin_layout Verbatim
//- error handling (see previous cases)
\end_layout

\begin_layout Verbatim
    }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
catch (const DevFailed& df)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- see below
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
rl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Note: if we want to execute the command locally on "cell-01" (i.e.
 not on its sub-groups), we should write the following code
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
//- get a reference to the target group
\end_layout

\begin_layout Verbatim
Tango::Group *g = gauges->get_group("cell-01");
\end_layout

\begin_layout Verbatim
//- get number of device in the group
\end_layout

\begin_layout Verbatim
long n_dev = g->get_size(false);
\end_layout

\begin_layout Verbatim
//- Build value list
\end_layout

\begin_layout Verbatim
std::vector<double> values(n_dev);
\end_layout

\begin_layout Verbatim
//- value for inst-c01/vac-gauge/penning-01
\end_layout

\begin_layout Verbatim
values[0] = 2 * 3.14159;
\end_layout

\begin_layout Verbatim
//- value for inst-c01/vac-gauge/penning-02
\end_layout

\begin_layout Verbatim
values[1] = 3 * 3.14159;
\end_layout

\begin_layout Verbatim
//- value for remaining devices in cell-01.penning
\end_layout

\begin_layout Verbatim
.
 .
 .
\end_layout

\begin_layout Verbatim
//- the reply list
\end_layout

\begin_layout Verbatim
Tango::GroupReplyList rl;
\end_layout

\begin_layout Verbatim
//- enter a try/catch block (see below)
\end_layout

\begin_layout Verbatim
try
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- write the "dummy" attribute
\end_layout

\begin_layout Verbatim
   rl = g->write_attribute("dummy", values, false);
\end_layout

\begin_layout Verbatim
   if (rl.has_failed())
\end_layout

\begin_layout Verbatim
   {
\end_layout

\begin_layout Verbatim
//- error handling (see previous cases)
\end_layout

\begin_layout Verbatim
   }
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
catch (const DevFailed& df)
\end_layout

\begin_layout Verbatim
{
\end_layout

\begin_layout Verbatim
//- see below
\end_layout

\begin_layout Verbatim
}
\end_layout

\begin_layout Verbatim
rl.reset();
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
This form of 
\emph on
write_attribute()
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
write-attribute
\end_layout

\end_inset


\emph default
 (the one that accepts an array of value as its input argument), may throw
 an exception before executing the command if the number of elements in
 the input array does not match the number of individual devices in the
 group or in the hierarchy (depending on the forward option).
 
\end_layout

\begin_layout Standard
An asynchronous version of this method is also available.
\end_layout

\begin_layout Section
Reading/Writing device pipe
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout

\series medium
pipe
\end_layout

\end_inset


\end_layout

\begin_layout Standard
Reading or writing device pipe is made possible using DeviceProxy class
 methods.
 To read a pipe, you have to use the method 
\series bold
read_pipe()
\series default
.
 To write a pipe, use the 
\series bold
write_pipe()
\series default
 method.
 A method 
\series bold
write_read_pipe()
\series default
 is also provided in case you need to write then read a pipe in a non-interuptib
le way.
 All these calls generate synchronous request and support only reading or
 writing a single pipe at a time.
 Those pipe related DeviceProxy class methods (read_pipe, write_pipe,...) use
 DevicePipe class instances.
 A DevicePipe
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DevicePipe
\end_layout

\end_inset

 instance is nothing more than a string for the pipe name and a 
\emph on
DevicePipeBlob
\emph default
 instance called the root blob.
 In a DevicePipeBlob
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DevicePipeBlob
\end_layout

\end_inset

 instance, you have:
\end_layout

\begin_layout Itemize
The blob name
\end_layout

\begin_layout Itemize
One array of 
\emph on
DataElement.
 
\emph default
Each instance of this DataElement class has:
\end_layout

\begin_deeper
\begin_layout Itemize
A name
\end_layout

\begin_layout Itemize
A value which can be either
\end_layout

\begin_deeper
\begin_layout Itemize
Scalar or array of any basic Tango type
\end_layout

\begin_layout Itemize
Another DevicePipeBlob
\end_layout

\end_deeper
\end_deeper
\begin_layout Standard
Therefore, this is a recursive data structure and you may have DevicePipeBlob
 in DevicePipeBlob.
 There is no limit on the depth of this recursivity even if it is not recommende
d to have a too large depth.
 The following figure summarizes DevicePipe data structure
\begin_inset Float figure
placement H
wide false
sideways false
status open

\begin_layout Plain Layout
\align center
\begin_inset Graphics
	filename pipe.eps
	width 14cm
	height 8cm

\end_inset


\end_layout

\begin_layout Plain Layout
\begin_inset Caption

\begin_layout Plain Layout
DevicePipe data structure
\begin_inset CommandInset label
LatexCommand label
name " "

\end_inset


\end_layout

\end_inset


\end_layout

\end_inset


\end_layout

\begin_layout Standard
Many methods to insert/extract data into/from a DevicePipe are available.
 In the DevicePipe class, these methods simply forward their action to the
 DevicePipe root blob.
 The same methods are available in the DevicePipeBlob in case you need to
 use the recursivity provided by this data structure.
\end_layout

\begin_layout Subsection
Reading a pipe
\end_layout

\begin_layout Standard
When you read a pipe, you have to extract data received from the pipe.
 Because data transferred through a pipe can change at any moment, two different
s cases are possible:
\end_layout

\begin_layout Enumerate
The client has a prior knowledge of what should be transferred through the
 pipe
\end_layout

\begin_layout Enumerate
The client does not know at all what has been received through the pipe
\end_layout

\begin_layout Standard
Those two cases are detailed in the following sub-chapters.
\end_layout

\begin_layout Subsubsection
Extracting data with pipe content prior knowledge
\end_layout

\begin_layout Standard
To extract data from a DevicePipe object (or from a DevicePipeBlob object),
 you have to use its extraction operator ">>".
 Let's suppose that we already know (prior knowledge) that the pipe contains
 3 data elements with a Tango long, an array of double and finally an array
 of unsigned short.
 The code you need to extract these data is (Without error case treatment
 detailed in a next sub-chapter)
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
1 DevicePipe dp = mydev.read_pipe("MyPipe");
\end_layout

\begin_layout Verbatim
2 
\end_layout

\begin_layout Verbatim
3 DevLong dl;  
\end_layout

\begin_layout Verbatim
4 vector<double> v_db;  
\end_layout

\begin_layout Verbatim
5 DevVarUShortArray *dvush = new DevVarUShortArray();
\end_layout

\begin_layout Verbatim
6 
\end_layout

\begin_layout Verbatim
7 dp >> dl >> v_db >> dvush;
\end_layout

\begin_layout Verbatim
8
\end_layout

\begin_layout Verbatim
9 delete dvush;
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
The pipe is read at line 1.
 Pipe (or root blob) data extracttion is at line 7.
 As you can see, it is just a matter of chaining extraction operator (">>")
 into local data (declared line 3 to 5).
 In this example, the transported array of double is extracted into a C++
 vector while the unsigned short array is extracted in a Tango sequence
 data type.
 When you extract data into a vector, there is a unavoidable memory copy
 between the DevicePipe object and the vector.
 When you extract data in a Tango sequence data type, there is no memory
 copy but the extraction method consumes the memory and it is therefore
 caller responsability to delete the memory.
 This is the rule of line 9.
 If there is a DevicePipeBlob inside the DevicePipe, simply extract it into
 one instance of the DevicePipeBlob class.
\end_layout

\begin_layout Standard
You may notice that the pipe root blob data elements name are lost in the
 previous example.
 The Tango API also has a DataElement
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DataElement
\end_layout

\end_inset

 class which allows you to retrieve/set data element name.
 The following code is how you can extract pipe data and retrieve data element
 name (same pipe then previously)
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
1 DevicePipe dp = mydev.read_pipe("MyPipe");
\end_layout

\begin_layout Verbatim
2 
\end_layout

\begin_layout Verbatim
3 DataElement<DevLong> de_dl;  
\end_layout

\begin_layout Verbatim
4 DataElement<vector<double> > de_v_db;  
\end_layout

\begin_layout Verbatim
5 DataElement<DevVarUShortArray *> de_dvush(new DevVarUShortArray());
\end_layout

\begin_layout Verbatim
6 
\end_layout

\begin_layout Verbatim
7 dp >> de_dl >> de_v_db >> de_dvush;
\end_layout

\begin_layout Verbatim
8
\end_layout

\begin_layout Verbatim
9 delete de_dvush.value;
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
The extraction line (number 7) is similar to the previous case but local
 data are instances of DataElement class.
 This is template class and instances are created at lines 4 to 6.
 Each DataElement instance has only two elements which are:
\end_layout

\begin_layout Enumerate
The data element name (a C++ string): 
\emph on
name
\end_layout

\begin_layout Enumerate
The data element value (One instance of the template parameter): 
\emph on
value
\end_layout

\begin_layout Subsubsection
Extracting data in a generic way (without prior knowledge)
\end_layout

\begin_layout Standard
Due to the dynamicity of the data transferred through a pipe, the API alows
 to extract data from a pipe without any prior knowledge of its content.
 This is achived with methods 
\emph on
get_data_elt_nb()
\emph default
, 
\emph on
get_data_elt_type()
\emph default
, 
\emph on
get_data_elt_name()
\emph default
 and the extraction operator ">>".
 These methods belong to the DevicePipeBlob class but they also exist on
 the DevicePipe class for its root blob.
 Here is one example of how you use them:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
1  DevicePipe dp = mydev.read_pipe("MyPipe");
\end_layout

\begin_layout Verbatim
2
\end_layout

\begin_layout Verbatim
3  size_t nb_de = dp.get_data_elt_nb();  
\end_layout

\begin_layout Verbatim
4  for (size_t loop = 0;loop < nb;loop++)
\end_layout

\begin_layout Verbatim
5  {      
\end_layout

\begin_layout Verbatim
6     int data_type = dp.get_data_elt_type(loop);      
\end_layout

\begin_layout Verbatim
7     string de_name = dp.get_data_elt_name(loop);      
\end_layout

\begin_layout Verbatim
8     switch(data_type)      
\end_layout

\begin_layout Verbatim
9     {         
\end_layout

\begin_layout Verbatim
10        case DEV_LONG:         
\end_layout

\begin_layout Verbatim
11        {             
\end_layout

\begin_layout Verbatim
12            DevLong lg;             
\end_layout

\begin_layout Verbatim
13            dp >> lg;         
\end_layout

\begin_layout Verbatim
14        }         
\end_layout

\begin_layout Verbatim
15        break;
\end_layout

\begin_layout Verbatim
16        
\end_layout

\begin_layout Verbatim
17        case DEVVAR_DOUBLEARRAY:         
\end_layout

\begin_layout Verbatim
18        {             
\end_layout

\begin_layout Verbatim
19            vector<double> v_db;             
\end_layout

\begin_layout Verbatim
20            dp >> v_db;         
\end_layout

\begin_layout Verbatim
21        }         
\end_layout

\begin_layout Verbatim
22        break;         
\end_layout

\begin_layout Verbatim
23        ....
      
\end_layout

\begin_layout Verbatim
24    }  
\end_layout

\begin_layout Verbatim
25    ...
  
\end_layout

\begin_layout Verbatim
26 }
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
The number of data element in the pipe root blob is retrieve at line 3.
 Then a loop for each data element is coded.
 For each data element, its value data type and its name are retrieved at
 lines 6 and 7.
 Then, according to the data element value data type, the data are extracted
 using the classical extraction operator (lines 13 or 20)
\end_layout

\begin_layout Subsubsection
Error management
\end_layout

\begin_layout Standard
By default, in case of error, the DevicePipe object throws different kind
 of exceptions according to the error kind.
 It is possible to disable exception throwing.
 If you do so, the code has to test the DevicePipe state after extraction.
 The possible error cases are:
\end_layout

\begin_layout Itemize
DevicePipe object is empty
\end_layout

\begin_layout Itemize
Wrong data type for extraction (For instance extraction into a double data
 while the DataElement contains a string)
\end_layout

\begin_layout Itemize
Wrong number of DataElement (Extraction code extract 5 data element while
 the pipe contains only four)
\end_layout

\begin_layout Itemize
Mix of extraction (or insertion) method kind (classical operators << or
 >>) and [] operator.
\end_layout

\begin_layout Standard
Methods 
\emph on
exceptions()
\emph default
 and 
\emph on
reset_exceptions()
\emph default
 of the DevicePipe and DevicePipeBlob classes allow the user to select which
 kind of error he is interested in.
 For error treatment without exceptions, methods 
\emph on
has_failed()
\emph default
 and 
\emph on
state()
\emph default
 has to be used.
 See reference documentation for details about these methods.
\end_layout

\begin_layout Subsection
Writing a pipe
\end_layout

\begin_layout Standard
Writing data into a DevicePipe or a DevicePipeBlob is similar to reading
 data from a pipe.
 The main method is the insertion operator "<<".
 Let's have a look at a first example if you want to write a pipe with a
 Tango long, a vector of double and finally an array of unsigned short.
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
1  DevicePipe dp("MyPipe");
\end_layout

\begin_layout Verbatim
2 
\end_layout

\begin_layout Verbatim
3  vector<string> de_names {"FirstDE","SecondDE","ThirdDE"};
\end_layout

\begin_layout Verbatim
4  db.set_data_elt_names(de_names);
\end_layout

\begin_layout Verbatim
5
\end_layout

\begin_layout Verbatim
6  DevLong dl = 666;  
\end_layout

\begin_layout Verbatim
7  vector<double> v_db {1.11,2.22};
\end_layout

\begin_layout Verbatim
8  unsigned short *array = new unsigned short [100];
\end_layout

\begin_layout Verbatim
9  DevVarUShortArray *dvush = create_DevVarUShortArray(array,100);
\end_layout

\begin_layout Verbatim
10
\end_layout

\begin_layout Verbatim
11 try  
\end_layout

\begin_layout Verbatim
12 {     
\end_layout

\begin_layout Verbatim
12    dp << dl << v_db << dvush;
\end_layout

\begin_layout Verbatim
13    mydev.write_pipe(dp);
\end_layout

\begin_layout Verbatim
14 }
\end_layout

\begin_layout Verbatim
15 catch (DevFailed &e)
\end_layout

\begin_layout Verbatim
16 {     
\end_layout

\begin_layout Verbatim
17    cout << "DevicePipeBlob insertion failed" << endl;     
\end_layout

\begin_layout Verbatim
18    ....
  
\end_layout

\begin_layout Verbatim
19 }
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Insertion into the DevicePipe is done at line 12 with the insert operators.
 The main difference with extracting data from the pipe is at line 3 and
 4.
 When inserting data into a pipe, you need to FIRST define its number od
 name of data elements.
 In our example, the device pipe is initialized to carry three data element
 and the names of these data elements is defined at line 4.
 This is a mandatory requirement.
 If you don't define data element number, exception will be thrown during
 the use of insertion methods.
 The population of the array used for the third pipe data element is not
 represented here.
\end_layout

\begin_layout Standard
It's also possible to use DataElement class instances to set the pipe data
 element.
 Here is the previous example modified to use DataElement class.
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
1  DevicePipe dp("MyPipe");
\end_layout

\begin_layout Verbatim
2
\end_layout

\begin_layout Verbatim
3  DataElement<DevLong> de_dl("FirstElt",666);  
\end_layout

\begin_layout Verbatim
4  vector<double>  v_db {1.11,2.22};
\end_layout

\begin_layout Verbatim
5  DataElement<vector<double> > de_v_db("SecondElt,v_db);
\end_layout

\begin_layout Verbatim
6
\end_layout

\begin_layout Verbatim
7  unsigned short *array = new unsigned short [100];
\end_layout

\begin_layout Verbatim
8  DevVarUShortArray *dvush = create_DevVarUShortArray(array,100);
\end_layout

\begin_layout Verbatim
9  DataElement<DevVarUShortArray *> de_dvush("ThirdDE",array);
\end_layout

\begin_layout Verbatim
10
\end_layout

\begin_layout Verbatim
11 try  
\end_layout

\begin_layout Verbatim
12 {     
\end_layout

\begin_layout Verbatim
12    dp << de_dl << de_v_db << de_dvush;
\end_layout

\begin_layout Verbatim
13    mydev.write_pipe(dp);
\end_layout

\begin_layout Verbatim
14 }
\end_layout

\begin_layout Verbatim
15 catch (DevFailed &e)
\end_layout

\begin_layout Verbatim
16 {     
\end_layout

\begin_layout Verbatim
17    cout << "DevicePipeBlob insertion failed" << endl;     
\end_layout

\begin_layout Verbatim
18    ....
  
\end_layout

\begin_layout Verbatim
19 }
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
The population of the array used for the third pipe data element is not
 represented here.
 Finally, there is a third way to insert data into a device pipe.
 You have to defined number and names of the data element within the pipe
 (similar to first insertion method) but you are able to insert data into
 the data element in any order using the "[]" operator overwritten for the
 DevicePipe and DevicePipeBlob classes.
 Look at the following example:
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Verbatim
1  DevicePipe dp("MyPipe");
\end_layout

\begin_layout Verbatim
2 
\end_layout

\begin_layout Verbatim
3  vector<string> de_names {"FirstDE","SecondDE","ThirdDE"};
\end_layout

\begin_layout Verbatim
4  db.set_data_elt_names(de_names);
\end_layout

\begin_layout Verbatim
5
\end_layout

\begin_layout Verbatim
6  DevLong dl = 666;  
\end_layout

\begin_layout Verbatim
7  vector<double> v_db = {1.11,2.22};
\end_layout

\begin_layout Verbatim
8  unsigned short *array = new unsigned short [100];
\end_layout

\begin_layout Verbatim
9  DevVarUShortArray *dvush = create_DevVarUShortArray(array,100);
\end_layout

\begin_layout Verbatim
10
\end_layout

\begin_layout Verbatim
11 dp["SecondDE"] << v_db;
\end_layout

\begin_layout Verbatim
12 dp["FirstDE"] << dl;
\end_layout

\begin_layout Verbatim
13 dp["ThirdDE"] << dvush;
\end_layout

\begin_layout Standard
\begin_inset CommandInset include
LatexCommand input
filename "line.tex"

\end_inset


\end_layout

\begin_layout Standard
Insertion into the device pipe is now done at lines 11 to 13.
 The population of the array used for the third pipe data element is not
 represented here.
 Note that the data element name is case insensitive.
\end_layout

\begin_layout Subsubsection
Error management
\end_layout

\begin_layout Standard
When inserting data into a DevicePipe or a DevicePipeBlob, error management
 is very similar to reading data from from a DevicePipe or a DevicePipeBlob.
 The difference is that there is one moer case which could trigger one exception
 during the insertion.
 This case is
\end_layout

\begin_layout Itemize
Insertion into the DevicePipe (or DevicePipeBlob) if its data element number
 have not been set.
\end_layout

\begin_layout Section
Device locking
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
Locking
\end_layout

\end_inset


\end_layout

\begin_layout Standard
Starting with Tango release 7 (and device inheriting from Device_4Impl),
 device locking is supported.
 For instance, this feature could be used by an application doing a scan
 on a synchrotron beam line.
 In such a case, you want to move an actuator then read a sensor, move the
 actuator again, read the sensor...You don't want the actuator to be moved
 by another client while the application is doing the scan.
 If the application doing the scan locks the actuator device, it will be
 sure that this device is "reserved" for the application doing the scan
 and other client will not be able to move it until the scan application
 un-locks this actuator.
\end_layout

\begin_layout Standard
A locked device is protected against:
\end_layout

\begin_layout Itemize

\emph on
command_inout
\emph default
 call except for device state and status requested via command and for the
 set of commands defined as allowed following the definition of allowed
 command in the Tango control access schema.
\end_layout

\begin_layout Itemize

\emph on
write_attribute
\emph default
 and 
\emph on
write_pipe
\emph default
 call
\end_layout

\begin_layout Itemize

\emph on
write_read_attribute, write_read_attributes
\emph default
 and 
\emph on
write_read_pipe
\emph default
 call
\end_layout

\begin_layout Itemize

\emph on
set_attribute_config 
\emph default
and
\emph on
 set_pipe_config
\emph default
 call
\end_layout

\begin_layout Itemize
polling and logging commands related to the locked device
\end_layout

\begin_layout Standard
Other clients trying to do one of these calls on a locked device will get
 a DevFailed exception.
 In case of application with locked device crashed, the lock will be automatical
ly release after a defined interval.
 The API provides a set of methods for application code to lock/unlock device.
 These methods are:
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::lock()
\emph default
 and 
\emph on
DeviceProxy::unlock()
\emph default
 to lock/unlock device
\end_layout

\begin_layout Itemize

\emph on
DeviceProxy::locking_status()
\emph default
, 
\emph on
DeviceProxy::is_locked()
\emph default
, 
\emph on
DeviceProxy::is_locked_by_me()
\emph default
 and 
\emph on
DeviceProxy::get_locker()
\emph default
 to get locking information
\end_layout

\begin_layout Standard
These methods are precisely described in the API reference chapters.
\end_layout

\begin_layout Section
Reconnection
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
reconnection
\end_layout

\end_inset

 and exception
\end_layout

\begin_layout Standard
The Tango API automatically manages re-connection between client and server
 in case of communication error during a network access between a client
 and a server.
 By default, when a communication error occurs, an exception is returned
 to the caller and the connection is internally marked as bad.
 On the next try to contact the device, the API will try to re-build the
 network connection.
 With the 
\emph on
set_transparency_reconnection
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
set-transparency-reconnection
\end_layout

\end_inset

()
\emph default
 method of the DeviceProxy
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
DeviceProxy
\end_layout

\end_inset

 class, it is even possible not to have any exception thrown in case of
 communication error.
 The API will try to re-build the network connection as soon as it is detected
 as bad.
 This is the default mode.
 See 
\begin_inset CommandInset ref
LatexCommand ref
reference "sec:Reconnection-and-exception"

\end_inset

 for more details on this subject.
\end_layout

\begin_layout Section
Thread
\begin_inset Index idx
status collapsed

\begin_layout Plain Layout
thread
\end_layout

\end_inset

 safety
\end_layout

\begin_layout Standard
Starting with Tango 7.2, some classes of the C++ API has been made thread
 safe.
 These classes are:
\end_layout

\begin_layout Itemize
DeviceProxy
\end_layout

\begin_layout Itemize
Database
\end_layout

\begin_layout Itemize
Group
\end_layout

\begin_layout Itemize
ApiUtil
\end_layout

\begin_layout Itemize
AttributeProxy
\end_layout

\begin_layout Standard
This means that it is possible to share between threads a pointer to a DevicePro
xy instance.
 It is safe to execute a call on this DeviceProxy instance while another
 thread is also doing a call to the same DeviceProxy instance.
 Obviously, this also means that it is possible to create thread local DevicePro
xy instances and to execute method calls on these instances.
 Nevertheless, data local to a DeviceProxy instance like its timeout are
 not managed on a per thread basis.
 For a DeviceProxy instance shared between two threads, if thread 1 changes
 the instance timeout, thread 2 will also see this change.
\end_layout

\begin_layout Section
Compiling and linking a Tango client
\end_layout

\begin_layout Standard
Compiling and linking a Tango client is similar to compiling and linking
 a Tango device server.
 Please, refer to chapter "Compiling, Linking and executing a Tango device
 server process" (
\begin_inset CommandInset ref
LatexCommand ref
reference "sec:Compiling,-linking-and"

\end_inset

) to get all the details.
\end_layout

\begin_layout Standard
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
begin{center}
\end_layout

\end_inset


\end_layout

\begin_layout Standard
\begin_inset CommandInset label
LatexCommand label
name "ThreeRicardo"

\end_inset


\begin_inset Graphics
	filename ../dance/0066-reduc.jpg
	lyxscale 80
	scale 200

\end_inset


\end_layout

\begin_layout Standard
\begin_inset ERT
status collapsed

\begin_layout Plain Layout


\backslash
end{center}
\end_layout

\end_inset


\end_layout

\end_body
\end_document
