pvDatabase Plugin Support

editions

2019.06.21
Original
2021.04.04
Update
Editors:
Marty Kraimer

This product is available via an open source license

Table of Contents

PVDatabase Plugin Support

NOTE: Plugin support via pvRequest is only implemented in C++ and only in: pvDatabaseCPP

Overview

Both record and field options can be specified. This section provides some details about support for field options.

Some examples are:

Field Plugin Filters

pvCopy implements plugin filters that can optionally be attached to fields accessed via pvCopy. Thus, if a channel provider uses pvCopy, it automatically has plugin filter support.

pvCopy itself provides the following plugins: array, deadband, timestamp, and ignore. Other plugins can also be implemented and registered.

The following interfaces are used for implementing plugin filters: PVPlugin, PVFilter, and PVPluginRegistry.

PVPlugin

Method create is called when an instance of pvCopy is created by a channel provider.

interface PVPlugin {
    PVFilter create(String requestValue,PVCopy pvCopy,PVField master);
}
where
requestValue
The value part of a name=value request option.
pvCopy
The PVCopy to which the PVFilter will be attached.
master
The field in the master PVStructure to which the PVFilter will be attached.

Returns the PVFilter. A null is returned if master or requestValue is not appropriate for the plugin.

PVFilter

The method filter is called whenever pvCopy is used to access a field of the client PVStructure.

interface PVFilter {
    boolean filter(PVField copy,BitSet bitSet,boolean toCopy);
    String getName();
}
where
copy
The data for copy.
bitSet
The BitSet for copy.
toCopy
(true,false) means copy (from master to copy,from copy to master)

Returns (true,false) if filter modified destination.

PVPluginRegistry

class PVPluginRegistry {
    static void registerPlugin(String name,PVPlugin pvPlugin);
    static PVPlugin find(String name);
}
The arguments are:
name
The name part of a name=value request option.
pvPlugin
The plugin implementation.

The return value for find is the plugin implementation or null if no plugin with that name has been registered.

Array Plugin

This filter is used to retrieve parts of an array (subarrays and strided subarrays). It is modeled after the array Filter that is provided with epics base starting with the 3.15 releases.

This filter works for both get and put. It works for any scalarArray field. It has not been tested for structureArray or unionArray fields.

The syntax is one of the following:

[array=start]
[array=start:end]
[array=start:increment:end]

start and end both specify an index. increment must be a positive integer.

start and end can be a positive or negative integer. If negative it is relative to the end of the array with -1 meaning the last element.

Suppose that the master array is:

1,2,3,4,5,6,7,8,9,10

Then the get request

[array=0:4]
gets
1,2,3,4,5
The request:
[array=-3:-1]
gets
8,9,10
The request:
[array=2:5]
gets
3,4,5,6
The request:
[array=0:2:-1]
gets
0,2,4,6,8,10

Deadband Plugin

This filter is used to limit the changes to a numeric scalar field that are reported to a client. It is modeled after the deadband Filter that is provided with epics base starting with the 3.15 releases.

This filter only works for numeric scalar fields and only for toCopy.

The syntax is one of the following:

[deadband=abs:value]
[deadband=rel:value]
where
abs
The value must change by at least this amount since the last value the client received.
rel
The percentage amount the value must change since the last value the client received.

Proposed New Options

The following options could be added:

[deadband=skip:value]
[deadband=maxrate:value]
[deadband=maxvalue:value]
[deadband=minvalue:value]
where
skip
value is the number of changes to ignore between declaring an event.
maxrate
value is the maximum rate in seconds to declare events.
maxvalue
only values less than or equal to value cause an event.
minvalue
only values greater than or equal to value cause an event.

TimeStamp Plugin

This filter is used for accessing a timeStamp field. It is modeled after the timeStamp Filter that is provided with epics base starting with the 3.15 releases.

This filter only works for a timeStamp field.

The syntax is one of the following:

[timestamp=current]
[timestamp=copy]
where
current
Only works for toCopy=true. Instead of taking the timestamp from master the timeStamp for the client is set to the current time.
copy
Only works for toCopy=false. The timestamp in master is set equal to the timeStamp from the client.

Ignore Plugin

This is not an actual plugin but is handled by pvCopy itself. It is used to suppress sending data to a client unless other fields have changed.

The syntax is:

[ignore=true]
One of the examples shown at the beginning of this section shows how it can be used.

Examples

array

To see the array plugin in action.

pvput PVRdoubleArray value=[1,2,3,4,5,6,7,8,9,10]
...

then
pvget -r "value[array=1:2:9]" PVRdoubleArray
PVRdoubleArray [2,4,6,8,10]
then
pvput -r "value[array=1:2:9]" PVRdoubleArray [100,200,300,400,500]
...
then
pvget -r value PVRdoubleArray
PVRdoubleArray [1,100,3,200,5,300,7,400,9,500]

NOTE: The syntax for setting value, i. e.

value='[10,20,30]'
Also could be:
value='["10","20","30"]'
In fact if the element values are anything except an integer, each element should be enclosed in quotes.

deadband and ignore

In one window:

pvget -m -v -r "timeStamp[ignore=true],alarm[ignore=true],value[deadband=abs:1]" PVRdouble

Then in another window:

pvput PVRdouble 10
pvput PVRdouble 9.5
pvput PVRdouble 9
pvput PVRdouble 8.5
pvput PVRdouble 5

Appendix I: ignore semantics

Plugin ignore is not a separate plugin, but is implemented by pvCopy itself. This is because it needs to implement the following semantics:

If only fields with option ignore=true have been changed than no event is declared. But the next time any other field changes then all such fields that did get changed will also be part of the event data.

The channel provider for PVDatabase calls the following for channelGet:

notifyClient = pvCopy->updateCopySetBitSet

The channel provider for PVDatabase calls the following for monitor

bool result = pvCopy->updateCopyFromBitSet
Both update methods end with the statement:
return checkIgnore(copyPVStructure,bitSet);
This code is:
bool PVCopy::checkIgnore(
     PVStructurePtr const & copyPVStructure,
     BitSetPtr const & bitSet)
{
    if(!ignorechangeBitSet) {
        return (bitSet->nextSetBit(0)<0) ? false : true;
    }
    int32 numFields = copyPVStructure->getNumberFields();
    BitSet temp(numFields);
    temp = *bitSet;
    int32 ind = 0;
    while(true) {
        ind = ignorechangeBitSet->nextSetBit(ind);
        if(ind<0) break;
        temp.clear(ind);
        ind++;
        if(ind>=numFields) break;
    }
    return (temp.nextSetBit(0)<0) ? false : true;
}

Note that the code: