pvaClient

editions

2021.03.01
Original
2021.04.10
Update
Editors:
Marty Kraimer

This product is available via an open source license

Table of Contents

Overview

This document is the guide for pvaClientCPP, which is one of the components of EPICS-7 .
It is intended for developers that want to use pvaClientCPP. A guide for developers is available at developerGuide

pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API. Thus it is easier to use than pvAccess itself. In addition pvaClient provides many convenience methods.

Doxgen for pvaClient is located at: doxygen .

PvaClient Overview

NOTE: Before reading this overview, clone and build exampleCPP , which has examples that are referenced in this overview.

pvaClient is support for accessing a single channel. It provides the following:

callbacks
The pvAccess client code requires the client to implement callbacks. pvaClient implements the callbacks. Thus a client is not required to implement callbacks, but can optionally implement any desired callback,
convenience methods
pvaClient provides methods that require much less code by the client. These are mainly for channels that have a value field that is either a scalar or scalar array.
caching
A client can ask to connect to a channel without requiring calls to issueConnect and waitConnect. If a connection is made, then the channel is cached. This means that if the client makes further requests for the same channel it is already connected. Caching is also done for channelGets and channelPuts.

The client has many options for how to use pvaClient. The client be very simple or use additional features.

Lets take an example that will work for any channel that has a top level value field which is a numeric scalar.

An example to get data is:
double value = PvaClient::get("pva")->channel(channelName)->getDouble()

The following is psuedo code that shows what pvaClient does:

PvaClientPtr pvaClient = getSingleton()
PvaClientChannelPtr pvaClientChannel= getFromChannelCache()
if not in cache
   pvaClientChannel = createChannel(channelName,providerName);
       pvaClientChannel.connect(timeout)
           issueConnect()
           waitConnect(timeout)
           if fail raise exception
   add channel to cache.
PvaClientGetPtr pvaClientGet = getFromGetCache()
if not in cache
   pvaClientGet =createGet()
   pvaClientGet.connect()
      issueConnect()
      waitConnect(timeout)
      if fail raise exception
   add to getCache
pvaClientGet.get()
   issueGet
   waitGet(timeout+
   if fail raise exception
PvaClientGetDataPtr getData = pvaClientGet.getData()
value = getData.getDouble()
   if fail raise exception
return value

An example to put data is:

double value = 1;
PvaClient::get("pva")->channel(channelName)->putDouble(value);
where channelName is some channel.
exampleCPP/pvaClient has shortestPutGetDouble and shortestPutGetDouble, which provide example code.

It is also easy to get/put data to a channel that has a value field that is an array of any numeric scalar type.

An example to get data is:
shared_vector<double> value = PvaClient::get("pva")->channel(channelName)->getDoubleArray()

An example to put data is:
size_t num = 5;
shared_vector<double> data(num,0);
for(size_t i=0; i<num; ++i) data[i] = i;
PvaClient::get("pva")->channel(channelName)->putDoubleArray(freeze(data));

Note the following:

exceptions
If any problems are encountered, an exception is thrown.
caching
Whenever a channel first connects it is added to a channel cache. This is a huge performance improvement when a client makes more than one request. There is also a cache for channelGets and a cache for channelPuts.

A client can also access channels with a complex structure but has to do more work. Two features that make this possible are:

pvRequest
Many methods have a pvRequest argument, which allows the client to specify the set of fields desired.
pvaClientData
The data for a channel is made available via pvaClientData. One of the methods is getPVStructure, which gets the entire data for a particular pvRequest.

The next section is a tutorial based on examples from exampleCPP/exampleClient. The remaining sections provide a brief summary of all methods provided by pvaClient
Look at doxygen for details about each method,

Tutorial

Non-blocking Examples

These are examples that never block while waiting for a channel to connect. They are good examples for use by display manager tools that want to access channels via pvAccessCPP. The examples all use pvaClientCPP rather than pvAccessCPP itself.

Each example implements a class that can be used as a starting point for imlementing pvAccess channel connections for a display manager.

get

This example uses PvaClientGet. It supports help as follows:

mrk> bin/linux-x86_64/get -help
-p provider -r request -d debug channelNames
default
-p pva -r value,alarm,timeStamp -d false PVRdouble
mrk> 
The arguments are:
provider
This can be either pva or ca. ca only works if channelName is a accessable via the ca network protocol, e. g. it is the name of a DBRecord in a V3 IOC.
request
The request for creating the channel get,
debug
If true then debug messages are displayed.
channelNames
A list of channel names.

When the example is started a PvaClientChannel is created and issueConnect is called. The first time the channel connects a PvaChannelGet is created and issueConnect is called.

The example then enters a forever loop that waits for the client to enter some input. If exit is entered then the program exits. If anything else is entered a channel get is requested and the results displayed. Note that the example works if the channel is not connected.

An example is:

bin/linux-x86_64/get
provider pva channelName PVRdouble request value,alarm,timeStamp debug false
_____get starting__
Type exit to stop: 
channelGetConnect PVRdouble status Status [type=OK]
channelGetConnect PVRdouble status Status [type=OK]
get
channelGetDone PVRdouble status Status [type=OK]
changed PVRdouble
 = structure 
    double value 0
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 0
        int nanoseconds 0
        int userTag 0

bitSet {0}
Type exit to stop: 
exit

put

This example uses PvaClientPut. It supports help as follows:

mrk> bin/linux-x86_64/put -help
-p provider -r request -d debug channelNames
default
-p pva -r value -d false PVRdouble
mrk> 
The arguments are:
provider
This can be either pva or ca. ca only works if channelName is a accessable via the ca network protocol, e. g. it is the name of a DBRecord in a V3 IOC.
request
The request for creating the channel put,
debug
If true then debug messages are displayed.
channelNames
A list of channel names.

When the example is started a PvaClientChannel is created and issueConnect is called. The first time the channel connects a PvaChannelPut is created and issueConnect is called.

The example then enters a forever loop the lets the client enter commands. Two commands are accepted:

exit
The example terminates.
put
A channel put is requested
get
A PvaChannelPut::get is requested. The results are displayed.

Note that if a channel disconnects and reconnects between gets the example should continuue to work.

An example is:

bin/linux-x86_64/put -help
 -h -p provider -r request - d debug channelNames 
default
-p pva -r value -d false PVRdouble
mrk> bin/linux-x86_64/put PVRdouble PVRshort
provider pva channelName PVRdouble request value debug false
_____put starting__
enter one of: exit put get
put
enter value or values to put
4
getDone PVRdouble status Status [type=OK]
structure 
    double value 0

putDone PVRdouble status Status [type=OK]
getDone PVRshort status Status [type=OK]
structure 
    short value 4

enter one of: exit put get
putDone PVRshort status Status [type=OK]
get
enter one of: exit put get
getDone PVRdouble status Status [type=OK]
structure 
    double value 4

getDone PVRshort status Status [type=OK]
structure 
    short value 4


putGet

This example uses pvaClientPutGet. It supports help as follows:

mrk> bin/linux-x86_64/putGet -help
-p provider -r request -d debug channelNames
default
-p pva -r putField(argument)getField(result) -d false PVRhelloPutGet
mrk> 
The arguments are:
provider
This can be either pva or ca. ca only works if channelName is a accessable via the ca network protocol, e. g. it is the name of a DBRecord in a V3 IOC.
request
The request for creating the channel putGet,
debug
If true then debug messages are displayed.
channelNames
A list of channel names.

When the example is started a PvaClientChannel is created and issueConnect is called. The first time the channel connects a PvaChannelGet is created and issueConnect is called.

The example then enters a forever loop the lets the client enter commands. Two commands are accepted:

exit
The example terminates.
putGet
A putGet is requested. The results are displayed.
getPut
A getPut is requested. The results are displayed.
getGet
A getGet is requested. The results are displayed.

Note that if a channel disconnects and reconnects between gets the example should continuue to work.

An example is:

bin/linux-x86_64/putGet
provider pva channelName PVRhelloPutGet request putField(argument)getField(result) debug false
_____put starting__
enter one of: exit putGet getPut getGet
channelPutGetConnect PVRhelloPutGet status Status [type=OK]
putGet
enter value
Marty
structure 
    structure result
        string value "Hello 3"

structure 
    structure argument
        string value 3

structure 
    structure result
        string value "Hello Marty"

enter one of: exit putGet getPut getGet
getPut
enter one of: exit putGet getPut getGet
structure 
    structure argument
        string value Marty

getGet
enter one of: exit putGet getPut getGet
structure 
    structure result
        string value "Hello Marty"

monitor

This example uses pvaClientMonitor. It supports help as follows:

mrk> bin/linux-x86_64/monitor -help
-p provider -r request -d debug channelNames
default
-p pva -r value,alarm,timeStamp -d false PVRdouble
mrk> 
The arguments are:
provider
This can be either pva or ca. ca only works if channelName is a accessable via the ca network protocol, e. g. it is the name of a DBRecord in a V3 IOC.
request
The request for creating the channel get,
debug
If true then debug messages are displayed.
channelNames
A list of channel names.

When the example is started a PvaClientChannel is created and issueConnect is called. The first time the channel connects a PvaChannelMonitor is created and issueConnect is called.

The example then enters a forever loop the lets the client enter commands. Two commands are accepted:

exit
The example terminates.
stop
A stop request is issued
start
The client is asked to enter a new request and then PvaChannelMonitor::start is called with the new request.

Note that if a channel disconnects and reconnects between gets the example should continuue to work.

An example is:

bin/linux-x86_64/monitor -help
 -h -p provider -r request - d debug channelNames 
default
-p pva -r value,alarm,timeStamp -d false PVRdouble
mrk> bin/linux-x86_64/monitor PVRdouble PVRshort
provider pva channelName PVRdouble request value,alarm,timeStamp debug false
_____get starting__
channelStateChange PVRdouble isConnected false
channelStateChange PVRshort isConnected false
Enter: exit start stop
channelStateChange PVRdouble isConnected true
monitorConnect PVRdouble status Status [type=OK]
event PVRdouble
monitor 
changed
 = structure 
    double value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619184903
        int nanoseconds 418736113
        int userTag 0

overrun
channelStateChange PVRshort isConnected true
monitorConnect PVRshort status Status [type=OK]
event PVRshort
monitor 
changed
 = structure 
    short value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619184903
        int nanoseconds 419209576
        int userTag 0

overrun

Enter: exit start stop

getField.

This is an example that calls Channel::getField , i. e. it gets the introspection interface for a field of a channel.

This example supports help as follows:

mrk> bin/linux-x86_64/getField -help
 -h -p provider - d debug channelNames 
default
-p pva -d false PVRdouble

After it is started than each time you enter a field name the introspection interface for the specified field is displayed. A null field name returns the complete introspection interface for the channel. When exit is entered the example terminates.

An example is:

bin/linux-x86_64/getField PVRdouble
provider pva channelName PVRdouble debug false
_____getField starting__
Type exit, or a fieldname, or just enter return

Type exit, or a fieldname, or just enter return
getDone
structure
    double value
    time_t timeStamp
        long secondsPastEpoch
        int nanoseconds
        int userTag
    alarm_t alarm
        int severity
        int status
        string message

value
Type exit, or a fieldname, or just enter return

exit

putUnion

This is another example that creates a PvaClientPut that never blocks. It automatically handles channel connect and disconnects and also creates a PvaClientPut when the channel first connects.

The example implements a class ClientPut, which implements PvaClientChannelStateChangeRequester, and PvaClientPutRequester.

This example must be connected to a field that has type pvUnion.

This example supports help as follows:

mrk> bin/linux-x86_64/putUnion -help
 -h -p provider -r request - d debug channelNames 
default
-p pva -r value -d false PVRrestrictedUnion
The arguments are:
channelName
The name of the channel.
request
A request as defined in the convert facility of pvData
debug
If true then debug messages are displayed/

An example is:

bin/linux-x86_64/putUnion
provider pva channelName PVRrestrictedUnion request value debug false
_____putUnion starting__
Type exit to stop: 
channelPutConnect PVRrestrictedUnion status Status [type=OK]

value 
putDone PVRrestrictedUnion status Status [type=OK]
Type exit to stop: 
exit
mrk> bin/linux-x86_64/putUnion
provider pva channelName PVRrestrictedUnion request value debug false
_____putUnion starting__
Type exit to stop: 
channelPutConnect PVRrestrictedUnion status Status [type=OK]
2
value 2
putDone PVRrestrictedUnion status Status [type=OK]
Type exit to stop: 
exit

pvget PVRrestrictedUnion
PVRrestrictedUnion epics:nt/NTUnion:1.0 
    union value
        string  2
    time_t timeStamp 2021-04-23 09:51:33.365  
        long secondsPastEpoch 1619185893
        int nanoseconds 365061410
        int userTag 0

process

This is an example that issues a request to process a record. It supports help as follows:

bin/linux-x86_64/process -help
 -h - d debug channelNames 
default
 -d false PVRdouble

An example is:

bin/linux-x86_64/process PVRdouble
 channelName PVRdouble debug false
_____process starting__
exit or enter
channelProcessConnect PVRdouble status Status [type=OK]

processDone PVRdouble status Status [type=OK]
exit or enter
exit

addRecord

This is an example that issues a call a record that can add a record to an existing PVDatabase.
An example is:

bin/linux-x86_64/addRecord  PVRaddRecord PVRdouble temp
result=structure 
    structure result
        string status success

pvinfo temp
temp
Server: 10.0.0.194:5075
Type:
    structure
        double value
        time_t timeStamp
            long secondsPastEpoch
            int nanoseconds
            int userTag
        alarm_t alarm
            int severity
            int status
            string message

multiPutDouble

This an example that uses PvaClientMultiPutDouble.

bin/linux-x86_64/multiPutDouble -help
 -h -p provider -d debug  channelNames 
default
 -d  {10}[PVRbyte, PVRshort, PVRint, PVRlong, PVRubyte, PVRushort, PVRuint, PVRulong, PVRfloat, PVRdouble]

An example is:

bin/linux-x86_64/multiPutDouble
_____multiPutDouble starting_______
 channelNames {10}[PVRbyte, PVRshort, PVRint, PVRlong, PVRubyte, PVRushort, PVRuint, PVRulong, PVRfloat, PVRdouble]
Type exit or enter to put

first element
2
data={10}[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
put data ={10}[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
after put data
Type exit or enter to put
exit
_____multiPutDouble done_______

multiMonitorDouble

This an example that uses PvaClientMultiMonitorDouble.

bin/linux-x86_64/multiMonitorDouble -help
 -h -p provider -d debug  channelNames 
default
 -d  {10}[PVRbyte, PVRshort, PVRint, PVRlong, PVRubyte, PVRushort, PVRuint, PVRulong, PVRfloat, PVRdouble]

An example is:

bin/linux-x86_64/multiMonitorDouble
_____multiMonitorDouble starting_______
 channelNames {10}[PVRbyte, PVRshort, PVRint, PVRlong, PVRubyte, PVRushort, PVRuint, PVRulong, PVRfloat, PVRdouble]
Type exit or enter to poll

value={10}[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Type exit or enter to poll
exit
_____multiMonitorDouble done_______

multiGetDouble

This an example that uses PvaClientMultiGetDouble.

 bin/linux-x86_64/multiGetDouble -help
 -h -p provider -d debug  channelNames 
default
 -d  {10}[PVRbyte, PVRshort, PVRint, PVRlong, PVRubyte, PVRushort, PVRuint, PVRulong, PVRfloat, PVRdouble]

An example is:

bin/linux-x86_64/multiGetDouble
_____multiGetDouble starting_______
 channelNames {10}[PVRbyte, PVRshort, PVRint, PVRlong, PVRubyte, PVRushort, PVRuint, PVRulong, PVRfloat, PVRdouble]
Type exit or enter to get

value={10}[0, 4, 0, 0, 0, 0, 0, 0, 0, 4]
Type exit or enter to get
exit
_____multiGetDouble done_______

ntMultiPut

This an example that uses PvaClientNTMultiPut.

bin/linux-x86_64/ntMultiPut -help
 -h -p provider - d debug channelNames 
default
-p pva -d false {9}[PVRbyte, PVRshortArray, PVRint, PVRlongArray, PVRubyte, PVRushortArray, PVRdouble, PVRdoubleArray, PVRvariantUnion]

An example is:

bin/linux-x86_64/ntMultiPut -help
 -h -p provider - d debug channelNames 
default
-p pva -d false {9}[PVRbyte, PVRshortArray, PVRint, PVRlongArray, PVRubyte, PVRushortArray, PVRdouble, PVRdoubleArray, PVRvariantUnion]
mrk> bin/linux-x86_64/ntMultiPut
_____ntMultiPut starting_______
 channelNames {9}[PVRbyte, PVRshortArray, PVRint, PVRlongArray, PVRubyte, PVRushortArray, PVRdouble, PVRdoubleArray, PVRvariantUnion]
Type exit or enter to put

enter value
4
Type exit or enter to put
exit
___ntMultiPut done_______

pvget PVRvariantUnion
PVRvariantUnion epics:nt/NTUnion:1.0 
    any value
        string  4
    time_t timeStamp 2021-04-23 10:54:17.944  
        long secondsPastEpoch 1619189657
        int nanoseconds 943713188
        int userTag 0

ntMultiMonitor

This an example that uses PvaClientNTMultiMonitor.

bin/linux-x86_64/ntMultiMonitor -help
 -h -p provider -r request -v valueOnly - d debug channelNames 
default
-p pva -r value,alarm,timeStamp -v false -d false {8}[PVRbyte, PVRshortArray, PVRint, PVRlongArray, PVRubyte, PVRushortArray, PVRdouble, PVRdoubleArray]

An example is:

bin/linux-x86_64/ntMultiMonitor
_____ntMultiMonitor starting_______
 channelNames {8}[PVRbyte, PVRshortArray, PVRint, PVRlongArray, PVRubyte, PVRushortArray, PVRdouble, PVRdoubleArray]
Type exit or enter to poll

PVRbyte = structure 
    byte value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943653531
        int userTag 0

PVRshortArray = structure 
    short[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943675894
        int userTag 0

PVRint = structure 
    int value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943682101
        int userTag 0

PVRlongArray = structure 
    long[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943687594
        int userTag 0

PVRubyte = structure 
    ubyte value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943691279
        int userTag 0

PVRushortArray = structure 
    ushort[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943695179
        int userTag 0

PVRdouble = structure 
    double value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943701211
        int userTag 0

PVRdoubleArray = structure 
    double[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943706137
        int userTag 0

Type exit or enter to poll
no new data
Type exit or enter to poll
exit
_____ntMultiMonitor done_______

ntMultiGet

This an example that uses PvaClientNTMultiGet.

bin/linux-x86_64/ntMultiGet -help
 -h -p provider -r request -v valueOnly - d debug channelNames 
default
-p pva -r value,alarm,timeStamp -v false -d false {8}[PVRbyte, PVRshortArray, PVRint, PVRlongArray, PVRubyte, PVRushortArray, PVRdouble, PVRdoubleArray]

An example is:

bin/linux-x86_64/ntMultiGet 
_____ntMultiGet starting_______
 channelNames {8}[PVRbyte, PVRshortArray, PVRint, PVRlongArray, PVRubyte, PVRushortArray, PVRdouble, PVRdoubleArray]
Type exit or enter to get

PVRbyte = structure 
    byte value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943653531
        int userTag 0

PVRshortArray = structure 
    short[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943675894
        int userTag 0

PVRint = structure 
    int value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943682101
        int userTag 0

PVRlongArray = structure 
    long[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943687594
        int userTag 0

PVRubyte = structure 
    ubyte value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943691279
        int userTag 0

PVRushortArray = structure 
    ushort[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943695179
        int userTag 0

PVRdouble = structure 
    double value 4
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943701211
        int userTag 0

PVRdoubleArray = structure 
    double[] value [4]
    alarm_t alarm
        int severity 0
        int status 0
        string message 
    time_t timeStamp
        long secondsPastEpoch 1619189657
        int nanoseconds 943706137
        int userTag 0

Type exit or enter to get
exit
_____ntMultiGet done_______

Blocking Examples

These are examples only work if a channel is already connected when the client starts. They are examples that could be used by scripting tools.

examplePvaClientGet

This has a number of examples:

exampleDouble
This shows both a short and long way to get data from a scalar channel. The short way throws an execption if the request fails. The long way allows the client more control of looking for problems and blocking.
exampleDoubleArray
Like exampleDouble except the data is a scalarArray.

examplePvaClientMonitor

This is an example of creating a monitor on a channel. It monitors a scalar double field. It also issues puts to the same channel so that it can make the monitors occur.

examplePvaClientPut

This has the folllowing examples:

exampleDouble
This shows use of get, put, and monitor to a numeric scalar field.
exampleDoubleArray
This shows use of get, put, and monitor to a numeric scalar array field.

examplePvaClientProcess

This example makes a process request to a channel.

examplePvaClientMultiDouble

This is an example of using pvaClientMultiChannel, pvaClientMultiGetDouble, pvaClientMultiPutDouble, and pvaClientMultiMonitorDouble.

examplePvaClientNTMulti

This is an example of using pvaClientMultiChannel to get data as an NTMultiChannel.

helloWorldPutGet

This is an example of issuing a channelPutGet.

helloWorldRPC

This is an example of issuing a PvaClientRPC request.

testRequest

This provides a way to run CreateRequest by providing a string that is passed to createRequest.

Some examples are:

mrk> pwd
/home/epicsv4/masterCPP/exampleCPP/exampleClient
mrk> bin/linux-x86_64/testRequest
enter a string to pass to createRequest
mrk> bin/linux-x86_64/testRequest value
pvRequest
structure 
    structure field
        structure value
mrk> bin/linux-x86_64/testRequest "record[block=true],field(value[max_elem=1],alarm.timeStamp)"
pvRequest
structure 
    structure record
        structure _options
            string block true
    structure field
        structure value
            structure _options
                string max_elem 1
        structure alarm
            structure timeStamp

PvaClient

Brief Description

PvaClient has methods:

get              Get the single instance of PvaClient.
channel          Creates a channel and connects.
                 This blocks and can throw an exception.
createChannel    Create a channel without blocking.
setRequester     Set a message requester. Client can optionally call this.
getRequesterName Get the requester name.
message          Generate a message. Any code can call this.
clearRequester   Let pvaClient handle calls to message and getRequesterName.
showCache        Show the current channels in the cache.
cacheSize        Show the number of channels in the cache.
setDebug         Set if debug messages should be generated.
getDebug         Get the current debug status.

Class PvaClient is a class that is used by all the other pvaClient classes. An application that uses pvaClient must call:

PvaClientPtr pvaClient = PvaClient::get(providers);

before it uses any other pvaClient classes.

This is a singleton method, i. e. only one instance of PvaClient is created.

providers is a blank separated set of provider names. For example:

PvaClientPtr pvaClient = PvaClient::get("ca pva");

The providers ca and pva are special. For each of these a client context is created when the PvaClient is constructed and the context destroyed when PvaClient is deleted.

Requester

This is a class defined in pvAccessCPP. It's main method is message, which code calls when it wants to pass messages to the client. A client that calls PvaClient::setRequester must implememt this class.

It has two methods:

getRequesterName
The client must implement this method. The value is up to the client.
message
This is called whenever any message is being generated. If the client does not call PvaClient::setRequester then PvaClient displays the message on stdout.

Channel Caching

PvaClient has a method:

PvaClientChannelPtr channel(
    string const & channelName,
    string const &providerName = "pva",
    double timeOut = 5.0);

This method creates a PvaClientChannel and then connects to the channel.

If a call is successful then multiple calls to the same channelName and providerName share the same PvaClientChannel, i. e. the PvaClientChannel is cached.

pvaClientChannelGet and pvaClientChannelPut also implement caching.

For example consider a client that makes multiple calls like:

double value;
value =  pva->channel(channelName)->get()->getData()->getDouble();
...
value =  pva->channel(channelName)->get()->getData()->getDouble();

Only the first call creates a new PvaClientChannel and a new PvaClientGet. The second call reuses the cached PvaClientChannel and PvaClientGet.

PERFORMANCE NOTE:

If a client connects to many channels then the caching methods can cause poor network performance.

Non Cached Channels

PvaClient has a method:

PvaClientChannelPtr createChannel(
    string const & channelName,
    string const &providerName = "pva");

This method is just creates a new PvaClientChannel and returns it to the caller. The caller must call the PvaClientChannel connect methods.

PvaClientChannel

Brief Description

PvaClientChannel has methods:

The following are for connecting to a channel.
connect      Calls issueConnect and then waitConnect.
             This blocks and can throw an exception.
issueConnect Issue a connection request and return.
waitConnect  Wait until the channel connects.
             It returns Status, wich shows if channel connects.

The following are for getting data from a channel.
Except for createGet, all can throw an exception.
get             Get a PvaChannelGet from the cache or create a PvaChannelGet and connect.
createGet       Create a PvaChannelGet.
getDouble       Calls get and then get data as a double.
getString       Calls get and then get data as a string.
getDoubleArray  Calls get and then get data as a double array.
getStringArray  Calls get and then get data as a string array.

The following are for putting data to a channel.
Except for createPut, all can throw an exception.
put             Get a PvaChannelPut from the cache or create a PvaChannelPut and connect.
createPut       Create a PvaChannelPut.
putDouble       Put a double to the channel.
putString       Put s string to the channel.
putDoubleArray  Put an array of doubles to the channel.
putStringArray  Put an array of strings to the channel.

The following creates a PvaClientPutGet
createPutGet    Create a PvaChannelPutGet.

The following creates a PvaClientMonitor
monitor        Create a PvaChannelMonitor.
               Can throw an exception.
createMonitor  Create a PvaChannelMonitor.

The following creates a PvaClientProcess
createProcess  Create a PvaChannelProcess.

The following are for remote procedure calls.
rpc             Issues a PvaClientRPC request and returns result.
                Can throw an exception.
createRPC       Creates a PvaClientRPC. 

The following are convience methods
getChannelName  Get the name of the channel
getChannel      This is the pvAccces channel
showCache       Show what is in the channel cache.
cacheSize       Show the number of channels in the cache.

The following can optionally be called by the client to receive state changes
setStateChangeRequester Specify the client callback.

The following are methods of pvAccess:ChannelRequester
getRequesterName    Get the name of the requester.
message             Generate a message.
channelCreated      Client should never call this.
channelStateChange  Client should never call this.

pvaClientChannel is a synchronous wrapper for the pvAccess::Channel API, which is a callback based API. Thus it is easier to use than pvAccess::Channel itself.

An instance of PvaClientChannel connects to a single channel.
An instance can only be created via class PvaClient which has both synchronous methods, which block, and non blocking methods. The synchrouous methods block until a connection is made to the channel and throw an exception if a timeout occurs while trying to make a connection. The non blocking methods leave connection to the caller.

Connect: Blocking vs Non-Blocking

PvaClientChannel has methods:

connect
This calls issueConnect and then waitConnect. If waitConnect fails an exception is thrown. Since waitConnect is a blocking method so is this.
issueConnect
This is a request to connect to the channel. This is a non blocking call.
waitConnect
This waits for the server to respond to issueConnect. It blocks until the server responds or a timeout occurs.

Get and Put Caching

PvaClientChannel has methods:

PvaClientGetPtr get(std::string const & request);
PvaClientPutPtr put(std::string const & request);

Each of these caches. For example all calls to get with the same request will share the same PvaChannelGet

For example consider a client that makes multiple calls like:

double value;
value =  pva->channel(channelName)->get()->getData()->getDouble();
...
value =  pva->channel(channelName)->get()->getData()->getDouble();

Only the first call creates a new PvaClientChannel and a new PvaClientGet. The second call reuses the cached PvaClientChannel and PvaClientGet.

PvaClientChannelStateChangeRequester

PvaClientChannel has method setStateChangeRequester PvaClientChannelStateChangeRequester has the single method channelStateChange. It is called each time the channel connection status changes.

NOTE: The implementation must not call a method that blocks waiting for a response from the server. It it does the client may be blocked forever.

An example of illegal code is:

virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
{
    if(isConnected&&!pvaClientPut)
    {
       pvaClientPut  = pvaClientChannel->createPut(request);
       pvaClientPut->connect();
    }
}

This is illegal because the call to connect blocks.

The following is an example of legal code:

virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
{
    if(isConnected&&!pvaClientPut)
    {
       pvaClientPut  = pvaClientChannel->createPut(request);
       pvaClientPut->issueConnect();
    }
}

This is legal code because neither createPut or issueConnect blocks.

pvaClientData

PvaClientData

This is a base class for pvaClientGetData, pvaClientPutData, and pvaClientMonitorData

This class provides methods:

getStructure          Get the introspection interface.
getPVStructure        Get the data.
getChangedBitSet      Get a bitset that shows which fields have changed.
showChanged           Show the fields that have changed value.
hasValue              Is the value field a scalar?
NOTE: The following only apply if hasValue is true.
isValueScalar         Is the value field a scalar?
isValueScalarArray    Is the value field a scalar array?
getValue              Get the value field.
getScalarValue        Get a scalar value field.
getArrayValue         Get an array value field.
getScalarArrayValue   Get a scalar array value field.
getDouble             Get scalar value field as a double.
getString             Get value field as a string.
getDoubleArray        Get value field as a double array.
getStringArray        Get value field as a string array.
getAlarm              Get the top level alarm field if it exists.
getTimeStamp          Get the top level timeStamp field if it exists.
parse                 Accepts arguments of the form json or field='value',
                      where value is json syntax.
streamJSON            Generates JSON output from the current PVStructure,
                      and displays it on the output stream.
zeroArrayLength       Sets the length of all array fields to 0.

create                NOT called by client code
setMessagePrefix      NOT called by client code.
setData               NOT called by client.

PvaClientGetData

This class provides access to the data returned by the server via PvaChannelGet or PvaChannelPutGet. Thus the client only gets access to an instance by getting it from PvaChannelGet or PvaChannelPutGet.

It provides all the methods from the base class PVaClientData and does not add any methods.

PvaClientPutData

This class provides access to data to send to the server via a PvaChannelPut. It is created by PvaChannelPut or PvaChannelPutGet. Thus the client only gets access to an instance by getting it from PvaChannelPut or PvaChannelPutGet.

Note also that for all field types except union the BitSet for the data is updated by PvaChannelPut or PvaChannelPutGet whenever the client changes a field. For a union or unionArray field the client must update the BitSet.

It provides all the methods from the base class PVaClientData. PvaClientPutData provides the additional methods:

putDouble             Put scalar value field as a double.
putString             Put value field as a string.
putDoubleArray        Put value field as a double array.
putStringArray        Put value field as a string array.

PvaClientMonitorData

This class provides access to the data returned by calls to get data via PvaChannelMonitor

It provides all the methods from the base class PVaClientData. PvaClientMonitorData provides the additional methods:

getOverrunBitSet      How many fields have changed more than once since last monitor event.
showOverrun           Show the fields that have changed more than once since the last monitor event.
setData               NOT called by client.
create                NOT called by client

PvaClientGet

Brief Description

PvaClientGet has methods:

connect             Calls issueConnect and then waitConnect.
issueConnect        Issues a request to the server to create the server side of ChannelGet.
waitConnect         Blocks until server responds that it has created the ChannelGet.
get                 Calls issueGet and then waitGet.
issueGet            Issues a get request to the server.
waitGet             Blocks until the server send a message that the get is complete.
getData             Get the PvaClientGetData. Should only be called after get or waitGet.
setRequester        Set a pvaClientGetRequester.
getPvaClientChannel Get the PvaClientChannel.

An instance of PvaClientGet is created via a call to one of the following:

class PvaClientChannel
...
{
...
    PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)");
    PvaClientGetPtr createGet(std::string const & request = "");
    PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const &  pvRequest);
...
};

PvaClientGetRequester

This is a virtual class that can be implemented by a client that uses PvaClientGet. It has the methods:

virtual void channelGetConnect(
    const Status& status,
    PvaClientGetPtr const && clientGet) {}
virtual void getDone(
    const Status& status,
    PvaClientGetPtr const & clientGet) = 0;

The client must call

pvaClientGet->setRequester(shared_from_this());

after creating an instance of PvaClientGet.

PvaClientPut

Brief Description

PvaClientPut has methods:

connect             Calls issueConnect and then waitConnect.
issueConnect        Issues a request to the server to create the server side of ChannelPut.
waitConnect         Blocks until server responds that it has created the ChannelPut.
get                 Calls issueGet and then waitGet.
issueGet            Issues a request to the server to get the latest data for a ChannelPut.
waitGet             Blocks until the server send a message that the get is complete.
put                 Calls issuePut and then waitPut.
issuePut            Issues a put request to the server.
waitPut             Blocks until the server sends a message that the put is complete.
getData             Get the PvaClientPutData.
setRequester        Set a pvaClientPutRequester.
getPvaClientChannel Get the PvaClientChannel.

NOTE: Except for union fields pvaClientPut takes care of modifying the bitSet associated with the data sent to the server.

An instance of PvaClientPut is created via a call to one of the followimg:

class PvaClientChannel
...
{
...
    PvaClientPutPtr put(std::string const & request = "field(value,alarm,timeStamp)");
    PvaClientPutPtr createPut(std::string const & request = "");
    PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const &  pvRequest);
...
};

PvaClientPutRequester

This is a virtual class that can be implemented by a client that uses PvaClientPut. It has the methods:

virtual void channelPutConnect(
    const Status& status,
    PvaClientPutPtr const & clientPut) {}
virtual void getDone(
    const Status& status,
    PvaClientPutPtr const & clientPut) {}
virtual void putDone(
    const Status& status,
    PvaClientPutPtr const & clientPut) = 0;

The client must call

pvaClientPut->setRequester(shared_from_this());

after creating an instance of PvaClientPut.

PvaClientMonitor

Brief Description

PvaClientMonitor has methods:

connect             Calls issueConnect and then waitConnect.
issueConnect        Issues a request to the server to create the server side of ChannelMonitor.
waitConnect         Blocks until server responds that it has created the ChannelMonitor.
start               Start monitoring.
stop                Stop monitoring.
poll                Poll for a monitor event. If return is true, call getData.
waitEvent           Wait for event.
releaseEvent        Release the monitorElement returned by poll.
getData             Get the PvaClientMonitorData.
setRequester        Set a pvaClientMonitorRequester.
getPvaClientChannel Get the PvaClientChannel.

An instance of PvaClientPut is created via a call to one of the followimg:

class PvaClientChannel
...
{
...
    PvaClientMonitorPtr monitor(std::string const & request = "field(value,alarm,timeStamp)");
    PvaClientMonitorPtr monitor(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester);
    PvaClientMonitorPtr monitor(
        std::string const & request,
        PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester);
    PvaClientMonitorPtr createMonitor(std::string const & request = "field(value,alarm,timeStamp)");
    PvaClientMonitorPtr createMonitor(epics::pvData::PVStructurePtr const &  pvRequest);
...
};

PvaClientMonitorRequester

This is a virtual class that can be implemented by a client that uses PvaClientMonitor. It has the methods:

virtual void monitorConnect(epics::pvData::Status const & status,
        PvaClientMonitorPtr const & monitor,
        epics::pvData::StructureConstPtr const & structure);
virtual void event(PvaClientMonitorPtr const & monitor) = 0;
virtual void unlisten();

PvaClientProcess

Brief Description

PvaClientProcess has methods:

connect             Calls issueConnect and then waitConnect.
issueConnect        Issues a request to the server to create the server side of ChannelProcess.
waitConnect         Blocks until server responds that it has created the ChannelProcess.
process             Calls issueProcess and then waitProcess.
issueProcess        Issues a process request to the server.
waitProcess         Blocks until the server send a message that the process is complete.
setRequester        Set a pvaClientProcessRequester.
getPvaClientChannel Get the PvaClientChannel.

An instance of PvaClientProcess is created via a call to one of the followimg:

class PvaClientChannel
...
{
...
    PvaClientProcessPtr createProcess(std::string const & request = "");
    PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const &  pvRequest);
...
};

PvaClientProcessRequester

This is a virtual class that can be implemented by a client that uses PvaClientGet. It has the methods:

virtual void channelProcessConnect(
        const epics::pvData::Status& status,
        PvaClientProcessPtr const & clientProcess){}
virtual void processDone(
        const epics::pvData::Status& status,
        PvaClientProcessPtr const & clientProcess) = 0;

PvaClientPutGet

Brief Description

PvaClientPutGet has methods:

connect             Calls issueConnect and then waitConnect.
issueConnect        Issues a request to the server to create the server side of ChannelPut.
waitConnect         Block until server responds that it has created the ChannelPut.
putGet              Call issuePutGet and then waitPutGet.
issuePutGet         Issue a putGet and return immediately.
waitPutGet          Block until putGet completes.
getGet              Calls issueGetGet and then waitGetGet.
issueGetGet         Issues a request to the server to get the latest data for the get data.
waitGetGet          Block until the server send a message that the getGet is complete.
getPut              Calls issueGetPut and then waitGetPut.
issueGetPut         Issues a request to the server to get the latest data for the put data.
waitGetPut          Block until the server send a message that the getPut is complete.
getPutData          Get PvaClientPutData
getGetData          Get PvaClientGetData

NOTE: Except for union fields pvaClientPutGet takes care of modifying the bitSet associated with the data sent to the server.

An instance of PvaClientPutGet is created via a call to one of the followimg:

class PvaClientChannel
...
{
...
    PvaClientPutGetPtr createPutGet(std::string const & request);
    PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const &  pvRequest);
...
};

PvaClientPutGetRequester

This is a virtual class that can be implemented by a client that uses PvaClientPut. It has the methods:

virtual void channelPutGetConnect(
    const Status& status,
    PvaClientPutGetPtr const & clientPutGet) {}
virtual void putGetDone(
    const Status& status,
    PvaClientPutGetPtr const & clientPutGet) {}
virtual void getPutDone(
    const Status& status,
    PvaClientPutGetPtr const & clientPutGet) = 0;
virtual void getGetDone(
    const Status& status,
    PvaClientPutGetPtr const & clientPutGet) = 0;

The client must call

pvaClientPutGet->setRequester(shared_from_this());

after creating an instance of PvaClientPutGet.

PvaClientRPC

Brief Description

PvaClientRPC has methods:

create             called by PvaClientChannel::rpc or PvaClientChannel::createRPC
setResponseTimeout set timeout for waiting for a response
getResponseTimeout get response timeout
connect            call issueConnect and then waitConnect. exception if fail to connect        
issueConnect       issue a connect request
waitConnect        wait for connection
request            issue a request

An instance of PvaClientRPC is created via a call to one of the following:

class PvaClientChannel
...
{
...
    PvaClientRPCPtr createRPC();
    PvaClientRPCPtr createRPC(epics::pvData::PVStructurePtr const &  pvRequest);
...
};

PvaClientRPCRequester

This is a virtual class that must be implemented by a client that uses PvaClientRPC. It has the methods:

    virtual void requestDone(
        const epics::pvData::Status& status,
        PvaClientRPCPtr const & pvaClientRPC,
        epics::pvData::PVStructure::shared_pointer const & pvResponse)()

PvaClientMultiChannel Overview

NOTE: Before reading this overview, clone and build exampleCPP . This has examples that are referenced in this overview.

This is support for getting, putting, and monitoring multiple channels. Two kinds of support are available:

MultiDouble
Support for channels that have a numeric scalar value field.
NTMulti
Support for channels that have a value field with each channel having diferent tyoes.

exampleCPP/pvaClientMultiChannel has examples:

multiPutGetDouble
This supports get and put for a set of channels where each has a scalar value.
multiMonitorDouble
This supports monitor for a set of channels where each has a scalar value.
ntMultiPutGet
This supports get and put for a set of channels where each has value with type scalar, scalarArray, or union. Note that is more complex than the MultiDouble example.
ntMultiMonitor
This supports a set of channels where each has value of any type.

The following sections provide a brief summary of all methods provided by pvaClient
Look at doxygen for details about each method,

pvaClientMultiChannel

PvaMultiChannel is a synchronous interface for accessing multiple channels.

PvaClientMultiChannel

PvaClientMultiChannel has methods:

create                   Create.
getChannelNames          Get the array of channel names.
connect                  For each channel, create and issueConnect.
                         Then for each channel waitConnect.
allConnected             Are all channels connected?
connectionChange         Is there a connection change since last call to getIsConnected?
getIsConnected           Get an array of the connection state of each channel.
getPvaClientChannelArray Get an array of pvaClientChannels.
getPvaClient             Get the pvaClint.      
createGet                Create a PvaClientMultiGetDouble.         
createNTGet              Create a PvaClientNTMultiGet.
createPut                Create a PvaClientMultiPut.
createNTPut              Create a PvaClientNTMultiPut.
createMonitor            Create a PvaClientMultiMonitorDouble.
createNTMonitor          Create a PvaClientNTMultiMonitor.

PvaClientMultiGetDouble

PvaClientMultiGetDouble has methods:

connect Create a channelGet for each channel.
get     Get the data as a double array.

PvaClientNTMultiGet

PvaClientNTMultiGet has methods:

connect Connect to each chanel.
get     Get the data from each channel.
getData get the data as PvaClientNTMultiData.

PvaClientMultiPutDouble

PvaClientMultiPutDouble has methods:

connect    Create a channelPut for each channel.
put        Put the data via a double array

PvaClientNTMultiPut

PvaClientNTMultiPut has methods:

connect   Create a channelPut for each channel.
getValues Get a PVUnion array that client uses to specify values for put.
put       Put the data for each channel.

PvaClientMultiMonitorDouble

PvaClientMultiMonitorDouble has methods:

connect   Create a channelMonitor for each channel.
poll      Issue a poll request. Return (true,false) if new data available.
waitEvent Wait until poll returns true.
get       Get the data for the last poll as an array of double.

PvaClientNTMultiMonitor

PvaClientNTMultiMonitor has methods:

connect   Create a channelMonitor for each channel.
poll      Issue a poll request. Return (true,false) if new data available.
waitEvent Wait until poll returns true.
getData   Get the data for the last poll as a PvaClientNTMultiData.

PvaClientNTMultiData

PvaClientNTMultiData has methods:

getNTMultiChannel Get NTMultiChannel.
getNumber         Get the number of channels.
getTimeStamp      Get the timestamp when the last update was made.