V4 CA Client User Interface
Channel Access Client User Interface
Under V4, a ProcessVariable would no longer be limited to the current properties 'value', 'units', ... but allow the users to create CA servers and clients that understand new properties.
The low-level V4 CA client API is likely to be rather complex because it now needs to handle arbitrary property catalogs.
- There still needs to be an easy to use high-level API, not much more complex than the existing one.
- There needs to be access to CA from languages like Matlab in a way that's as easy as
pv = caopen('fred'); value = caget(pv);
Food for thought
Is there anything we can learn from other communication libraries?
- A brief look at ZeroC ICE
Skeleton API
What follows is in the form of pseudo classes and associated methods that a CA client API should provide.
Directory Server
- setServer(string URL-type-server-address)
Optional; otherwise some site-specific default name server is used. That 'URL' might contain a user & password, which decides if this name server connection is read-only (for OPI clients) or if writes are allowed (for IOCs that add PVs to the name server). - getChannelInfo(string PV_or_pattern)
Returns list of- CA server - IP & port of server that has the PV
- quality - is this the IOC, a gateway, backup/primary
- addChannelInfo(string PV, CASInfo addr_and_port, CASType primary_or_backup_or...)
Used by CA servers to register their PV in directory - deleteChannelInfo(string PV, CASInfo addr_and_port, CASType primary_or_backup_or...)
Used by CA servers to remove their PV from directory
Data Access
All the data is accessed via DataAccess, which handles the introspection of arbitrary data types. It should provide the following convenience routines in addition to whatever more efficient methods it might have:
- list<string> getProperties()
Get a list of all the properties - type_info getType(string property)
- string getAsString(string property)
Channel, General Methods
- getName()
Returns the name of the channel.
Channel, Connection Related Methods
- connect(CA server info)
Attempts to connect & maintain the connection with specific server - connect(string channel_name, string name_server URL = "")
Shortcut, probably used by most applications:
Queries name server (default one if left empty) and connect to the 'primary' PV. If down, tries 'backup'. If 'primary' resurfaces, switches back to it etc. - disconnect()
- addConnectionLister(connection_listener), removeConnectionLister(connection_listener)
.. for those who want to get notifications - bool isConnected()
.. for those who want to poll - xxx getServerInfo(), xxx getAccessType(), xxx getType()
.. only valid when isConnected().
Channel, 'Put' Related Methods
- put(new value)
Sends data to the server.
Returns error if currently disconnected or other local problem, no other feedback wether the value actually reached the server. - putNotify(new value), putCompletionNotify(new value)
Sends the value to the server, invokes putNotification when receiving record has received the value respectively all the processing triggered by the new value has completed. - addPutListener(pnl), removePutListener(pnl)
Need to register listener to actually receive the put*Notify info.
Channel, 'Get' Related Methods
- DataAccess = getData(property_list)
Waits for the data. - getDataNotify(property_list)
Will invoke DataListener once data arrives. - addDataListener(dn), removeDataListener(dl)
The data listener is invoked with the channel and the data access interface to the actual data.
In addition, does it include event information, so when it's in response to a subscription (see below), we know why the data was sent? Or is that event information embedded in DataAccess?
Channel, Subscription Related Methods
- addSubscription(event, filter)
- event: alarm condition change, some hardware event (like blue beam)
- filters: min/max period, range, rate of change, absolute change
- cancelSubscription(event, filter)
The idea is that the end result of a subscription is just like a getDataNotify, invoking the dataListener, except that a subscription will typically return data more than once. One can add more then one subscription to the same channel.
Container
The Channel does not store any data from a 'put', 'get' or subscription. When attaching a container to a channel, the container will subscribe to the channel and keep a copy of all data, so one can always ask the container for the current values.
- attach(channel)
- detach()
- implements the DataAccess interface to allow access to the data.
caget 101
This is how a simple 'caget' could be written:
Channel channel; channel.connect("fred"); DataAccess da = channel.get("value"); cout << "Value of " << channel.getName() << " : " << da.getAsString("value") << "\n"; channel.disconnect();