package org.epics.archiverappliance.engine.V4;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.Logger;
import org.epics.pvaccess.client.Channel;
import org.epics.pvaccess.client.Channel.ConnectionState;
import org.epics.pvaccess.client.ChannelProvider;
import org.epics.pvaccess.client.ChannelProviderRegistryFactory;
import org.epics.pvaccess.client.ChannelRequester;
import org.epics.pvdata.copy.CreateRequest;
import org.epics.pvdata.misc.BitSet;
import org.epics.pvdata.monitor.Monitor;
import org.epics.pvdata.monitor.MonitorElement;
import org.epics.pvdata.monitor.MonitorRequester;
import org.epics.pvdata.pv.MessageType;
import org.epics.pvdata.pv.PVStructure;
import org.epics.pvdata.pv.Status;
import org.epics.pvdata.pv.Structure;
/**
* Sample V4 client to explore the API a bit; feel free to delete this file if the API's change
* @author mshankar
*
*/
public class SampleV4Client implements ChannelRequester, MonitorRequester {
private static final Logger logger = Logger.getLogger(SampleV4Client.class);
private static ChannelProvider channelProvider;
private Channel channel;
List<String> fieldNames = new LinkedList<String>();
public SampleV4Client(String pvName) {
channel = channelProvider.createChannel(pvName, this, ChannelProvider.PRIORITY_DEFAULT);
}
public static void main(String[] args) {
org.epics.pvaccess.ClientFactory.start();
logger.info("Registered the pvAccess client factory.");
channelProvider = ChannelProviderRegistryFactory.getChannelProviderRegistry().getProvider(org.epics.pvaccess.ClientFactory.PROVIDER_NAME);
for(String providerName : ChannelProviderRegistryFactory.getChannelProviderRegistry().getProviderNames()) {
logger.info("PVAccess Channel provider " + providerName);
}
for(String pvName : args) {
new SampleV4Client(pvName);
}
}
@Override
public String getRequesterName() {
return "SampleV4Client";
}
@Override
public void message(String message, MessageType arg1) {
logger.debug(message);
}
@Override
public void channelCreated(Status arg0, Channel arg1) {
}
@Override
public void channelStateChange(Channel channelChangingState, ConnectionState connectionStatus) {
if (connectionStatus == ConnectionState.CONNECTED) {
logger.info("channelStateChange:connected " + channelChangingState.getChannelName());
PVStructure pvRequest = CreateRequest.create().createRequest("field()");
channel.createMonitor(this, pvRequest);
}
}
private void createFieldIdToNameIndex(List<String> fieldNames, Structure structure, String structureName) {
fieldNames.add(structureName);
for(String fieldName : structure.getFieldNames()) {
switch(structure.getField(fieldName).getType()) {
case structure: {
createFieldIdToNameIndex(fieldNames, (Structure) structure.getField(fieldName), structureName.isEmpty() ? fieldName : (structureName + "." + fieldName));
continue;
}
case scalar:
case scalarArray:
case structureArray:
case union:
case unionArray:
default: {
fieldNames.add(structureName.isEmpty() ? fieldName : (structureName + "." + fieldName));
continue;
}
}
}
}
@Override
public void monitorConnect(Status arg0, Monitor channelMonitor, Structure structure) {
createFieldIdToNameIndex(fieldNames, structure, "");
for(int i = 0; i < fieldNames.size(); i++) {
logger.info("Field " + i + " = " + fieldNames.get(i));
}
channelMonitor.start();
}
@Override
public void monitorEvent(Monitor monitor) {
MonitorElement monitorElement = null;
try {
monitorElement = monitor.poll();
while (monitorElement != null) {
try {
logger.info("Obtained monitor event for pv " + channel.getChannelName());
// PVStructure totalPVStructure = monitorElement.getPVStructure();
BitSet changedBits = monitorElement.getChangedBitSet();
logger.info("Obtained monitor event for pv " + channel.getChannelName() + " Changed bits: " + changedBits.toString());
for (int i = changedBits.nextSetBit(0); i >= 0; i = changedBits.nextSetBit(i+1)) {
logger.info("Field has changed: " + fieldNames.get(i));
}
} finally {
monitor.release(monitorElement);
}
monitorElement = monitor.poll();
}
} catch(Exception ex) {
logger.error("Exception processing monitor event", ex);
}
}
@Override
public void unlisten(Monitor arg0) {
}
}