|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
---|---|
ChannelWriteCallback | Called by the ChannelHandler once a write is completed. |
DataSourceTypeAdapter<ConnectionPayload,MessagePayload> | Matches and fills a cache with the data from connection and message payloads. |
DataSourceTypeAdapterSet | A set of type adapters. |
ExpressionLanguage.OneArgFunction<R,A> | A user provided single argument function. |
ExpressionLanguage.TwoArgFunction<R,A1,A2> | A user provided double argument function. |
PVReader<T> | An object representing the PVReader. |
PVReaderListener | Callback for any change in the PV value. |
PVWriter<T> | An object representing a writable PV. |
PVWriterListener | Callback for delivery notification of new value. |
Class Summary | |
---|---|
Aggregator<R,A> | Aggregates the data out of a Collector into a new data type. |
BasicTypeSupport | Implements support for basic standard java types. |
ChannelHandler | Manages the connection for each channel of a data source. |
ChannelHandlerReadSubscription | Groups all the parameters required to add a reader to a ChannelHandler. |
ChannelRecipe | |
Collector<T> | Collects the data at the CA rate and allows a client to get all values since last check. |
CompositeDataSource | A data source that can dispatch a request to multiple different data sources. |
DataRecipe | Represents all the information necessary to connect to a DataSource . |
DataRecipeBuilder | Builder class for DataRecipe . |
DataSource | A source for data that is going to be processed by the PVManager. |
DataSourceTypeSupport | The type support for a datasource. |
ExceptionHandler | This class receives all the exceptions generated by a PV. |
ExpressionLanguage | Operators to constructs expression of PVs that the PVManager will
be able to monitor. |
ExpressionLanguage.Filter<T> | Filters a data stream, removing updates that match the given function. |
Function<R> | A basic building block in the PVManager framework that can return a result of a given type. |
MultiplexedChannelHandler<ConnectionPayload,MessagePayload> | Implements a ChannelHandler on top of a single subscription and
multiplexes all reads on top of it. |
Notification<T> | Used by NotificationSupport to communicate whether a new notification
is needed, and what should be the type to be notified. |
NotificationSupport<T> | Dedicated notification type support. |
PV<R,W> | A PV that can be both read and written. |
PVConfiguration<R,W> | Allows to configure the type of read/write PV to create. |
PVManager | Entry point for the library, manages the defaults and allows to create
PVReader , PVWriter and PV from an read or write expression. |
PVReaderConfiguration<T> | An expression used to set the final parameters on how the pv expression should be monitored. |
PVWriterConfiguration<T> | An expression used to set the final parameters on how the pv expression should be written. |
TimeSupport<T> | Deprecated. generic type support is being removed: was too intrusive and little used. |
TypeSupport<T> | Implements the mechanism for registering different types so that the library knows how to handle them. |
ValueCache<T> | Represent a building block that can store a particular value |
WriteBuffer | Represents all the values, channel names and ordering information needed for writing |
WriteBufferBuilder | A builder for WriteBuffer . |
WriteCache<T> | Represent part of the write buffer that holds the value for one pv. |
WriteFunction<A> | A basic building block in the PVManager framework that can write an object of a given type. |
Exception Summary | |
---|---|
ReadFailException | Exception thrown when a PVReader is trying to read a channel or
data source that cannot be read from. |
TimeoutException | Exception thrown when a PVReader or PVWriter exceed their
timeout. |
WriteFailException | Exception thrown when a PVWriter is trying to write to a read-only
channel or data source. |
// Import from here import static org.csstudio.utility.pvmanager.ui.SWTUtil.*; // When creating a pv, remember to ask for notification on the SWT thread PVReader<?> pvReader = PVManager.read(...)..notifyOn(swtThread()).maxRate(ofMillis(100));
// Import from here import static org.epics.pvmanager.util.Executors.*; // Route notification for this pv on the Swing EDT PVReader<?> pvReader = PVManager.read(...).notifyOn(swingEDT()).maxRate(ofMillis(100)); // Or you can change the default PVManager.setDefaultNotificationExecutor(swingEDT());
// Sets CAJ (pure java implementation) as the default data source, // monitoring both value and alarm changes PVManager.setDefaultDataSource(new JCADataSource()); // For utltimate control, you can create the JCA context yourself // and pass it to the data source ... Context jcaContext = ... PVManager.setDefaultDataSource(new JCADataSource(jcaContext, Monitor.VALUE | Monitor.ALARM));For more options, check the constructors for
JCADataSource
.
// Create a multiple data source, and add different data sources CompositeDataSource composite = new CompositeDataSource(); composite.putDataSource("ca", new JCADataSource()); composite.putDataSource("sim", new SimulationDataSource()); // If no prefix is given to a channel, use JCA as default composite.setDefaultDataSource("ca"); // Set the composite as the default PVManager.setDefaultDataSource(composite);For more options, check the documentation for
CompositeDataSource
.
// Let's statically import so the code looks cleaner
import static org.epics.pvmanager.ExpressionLanguage.*;
import static org.epics.util.time.TimeDuration.*;
// Read channel "channelName" up to every 100 ms
final PVReader
<Object> pvReader = PVManager.read(channel("channelName")).maxRate(ofMillis(100));
pvReader.addPVReaderListener(new PVReaderListener() {
public void pvChanged() {
// Do something with each value
Object newValue = pvReader.getValue();
System.out.println(newValue);
}
});
// Remember to close
pvReader.close();
The interval between updates can be specified in different units (e.g. ms, sec, min, hour, hz).
Check the documentation at TimeDuration
.
// Read channel "channelName" up to every 100 ms, and get all
// the new values from the last notification.
final PVReader<List<Object>> pvReader = PVManager.read(newValuesOf
(channel("channelName"))).maxRate(ofMillis(100));
pvReader.addPVReaderListener(new PVReaderListener() {
public void pvChanged() {
// Do something with each value
for (Object newValue : pvReader.getValue()) {
System.out.println(newValue);
}
}
});
// Remember to close
pvReader.close();
To limit memory consumption, you can specify the maximum amount of values
to retain. See all options at ExpressionLanguage
.
PVWriter<Object> pvWriter = PVManager.write(channel("channelName")).async(); pvWriter.addPVWriterListener(new PVWriterListener() { public void pvWritten() { System.out.println("Write finished"); } }); // This will return right away, and the notification will be sent // on the listener pvWriter.write("New value"); // Remember to close pvWriter.close();
PVWriter<Object> pvWriter = PVManager.write(channel("channelName")).sync(); // This will block until the write is done pvWriter.write("New value"); System.out.println("Write finished"); // Remember to close pvWriter.close();
// A PV is both a PVReader and a PVWriter final PV<Object, Object> pv = PVManager.readAndWrite(channel("channelName")).asynchWriteAndMaxReadRate(ofMillis(10)); pv.addPVReaderListener(new PVReaderListener() { public void pvChanged() { // Do something with each value Object newValue = pv.getValue(); System.out.println(newValue); } }); pv.write("New value"); // Remember to close pv.close();
final PVReader<Object> pvReader = PVManager.read(channel("channelName")).maxRate(ofMillis(100)); pvReader.addPVReaderListener(new PVReaderListener() { public void pvChanged() { // By default, read exceptions are made available // on the reader itself. // This will give you only the last exception, so if // more then one exception was generated after the last read, // some will be lost. Exception ex = pvReader.lastException(); // Note that taking the exception, clears it // so next call you'll get null. if (pvReader.lastException() == null) { // Always true } } });
// All read exceptions will be passed to the exception handler
// on the thread that it generates them. The handler, therefore,
// must be thread safe. Overriding the exception handling means
// disabling the default handling, so read exception will no longer
// be accessible with pvReader.lastException()
final PVReader<Object> pvReader = PVManager.read(channel("channelName"))
.routeExceptionsTo(new ExceptionHandler() {
public void handleException(Exception ex) {
System.out.println("Error: " + ex.getMessage());
}
}).maxRate(ofMillis(100));
// If after 5 seconds no new value comes (i.e. pvReader.getValue() == null) // then a timeout is sent. PVManager will _still_ try to connect, // until pvReader.close() is called. // The timeout will be notified only on the first connection. final PVReader<Object> pvReader = PVManager.read(channel("channelName")).timeout(sec(5)).maxRate(ofMillis(100)); pvReader.addPVReaderListener(new PVReaderListener() { public void pvChanged() { // Timeout are passed as exceptions. This allows you to // treat them as any other error conditions. Exception ex = pvReader.lastException(); if (ex instanceof TimeoutException) { System.out.println("Didn't connected after 5 seconds"); } } });
// Read a map with the channels named "one", "two" and "three" final PVReader<Map<String, Object>> pvReader = PVManager.read(mapOf(latestValueOf(channels("one", "two", "three")))).maxRate(ofMillis(100)); pvReader.addPVReaderListener(new PVReaderListener() { public void pvChanged() { // Print the values if any Map<String, Object> map = pvReader.getValue(); if (map != null) { System.out.println("one: " + map.get("one") + " - two: " + map.get("two") + " - three: " + map.get("three")); } } }); // Remember to close pvReader.close();Note that when using a composite datasource, the channels can be from different sources (e.g. "sim://noise" and "ca://mypv").
// Write a map to the channels named "one", "two" and "three" PVWriter<Map<String, Object>> pvWriter = PVManager.write(mapOf(channels("one", "two", "three"))).async(); // Prepare the 3 values Map<String, Object> values = new HashMap<String, Object>(); values.put("one", 1.0); values.put("two", 2.0); values.put("three", "run"); // Write pvWriter.write(values); // Remember to close pvWriter.close();Note that when using a composite datasource, the channels can be from different sources (e.g. "sim://noise" and "ca://mypv").
// Read and write a map to the channels named "one", "two" and "three" PV<Map<String, Object>, Map<String, Object>> pv = PVManager.readAndWrite( mapOf(latestValueOf(channels("one", "two", "three")))).asynchWriteAndMaxReadRate(ofMillis(100)); // Do something // ... // Remember to close pv.close();
// Read a map with the channels "one", "two" and "three" // reffered in the map as "setpoint", "readback" and "difference" final PVReader<Map<String, Object>> pvReader = PVManager.read(mapOf( latestValueOf(channel("one").as("setpoint").and(channel("two").as("readback")).and(channel("three").as("difference"))))).maxRate(ofMillis(100)); pvReader.addPVReaderListener(new PVReaderListener() { public void pvChanged() { // Print the values if any Map<String, Object> map = pvReader.getValue(); if (map != null) { System.out.println("setpoint: " + map.get("setpoint") + " - readback: " + map.get("readback") + " - difference: " + map.get("difference")); } } }); // Remember to close pvReader.close();You can rename channels and any read expression, regardless of how they are combined later.
// Write a map to the channels named "one", "two" and "three" // Write "two" after "one" and write "three" after "two" PVWriter<Map<String, Object>> pvWriter = PVManager.write( mapOf(channel("one") .and(channel("two").after("one")) .and(channel("three").after("two")))).async(); // Do something // ... // Remember to close pvWriter.close();Note that when using a composite datasource, the channels can be from different sources (e.g. "sim://noise" and "ca://mypv"). The write ordering will also be respected across sources.
// Let's statically import so the code looks cleaner import static org.epics.pvmanager.data.ExpressionLanguage.*; // Read and Write a vDouble // Note that the read type is different form the write type final PV<VDouble, Double> pv = PVManager.readAndWrite(vDouble("currentRB")).asynchWriteAndMaxReadRate(ofMillis(100)); pv.addPVReaderListener(new PVReaderListener() { public void pvChanged() { VDouble value = pv.getValue(); if (value != null) { System.out.println(value.getValue() + " " + value.getAlarmSeverity()); } } }); pv.write(1.0); // Remember to close pv.close();For a full list of types, refer to
ExpressionLanguage
.
// We connect to a channel that produces a VType, but we // don't know which one final PVReader<VType> pvReader = PVManager.read(vType("channelName")).maxRate(ofMillis(100)); pvReader.addPVReaderListener(new PVReaderListener() { public void pvChanged() { VType value = pvReader.getValue(); // We can extract the different aspect of the read object, // so that we can work on them separately // This returns the interface implemented (VDouble, VInt, ...) Class<?> type = ValueUtil.typeOf(value); // Extracts the alarm if present Alarm alarm = ValueUtil.alarmOf(value); // Extracts the time if present Time time = ValueUtil.timeOf(value); // Extracts a numeric value if present Double number = ValueUtil.numericValueOf(value); // Extract display information if present Display display = ValueUtil.displayOf(value); setAlarm(alarm); // ... } });
final PVReader<VType> pvReader = PVManager.read(vType("channelName")).maxRate(ofMillis(100)); pvReader.addPVReaderListener(new PVReaderListener() { public void pvChanged() { // We can switch on the full type if (pvReader.getValue() instanceof VDouble) { VDouble vDouble = (VDouble) pvReader.getValue(); // Do something with a VDouble } // ... } });
final PVReader<VType> pvReader = PVManager.read(vType("channelName")).maxRate(ofMillis(100)); pvReader.addPVReaderListener(VDouble.class, new PVReaderListener() { public void pvChanged() { // We are already guaranteed that the cast succeeds // and that the value is not null VDouble vDouble = (VDouble) pvReader.getValue(); System.out.println(vDouble.getValue()); // ... } });
List<String> names = Arrays.asList("one", "two", "trhee"); final PVReader<VTable> pvReader = PVManager.read(vTable( column("Names", vStringConstants(names)), column("Values", latestValueOf(vType(names))))) .maxRate(ofMillis(100)); pvReader.addPVReaderListener(new PVReaderListener() { public void pvChanged() { VTable vTable = pvReader.getValue(); // First column is the names String[] names = (String[]) vTable.getColumnArray(0); // Second column is the values double[] values = (double[]) vTable.getColumnArray(1); // ... } });
There are two distinct parts in the PVManager framework. The first part
includes all the elements that deal with data directly: read from various
sources (DataSource
), performing computation (Function
),
collecting data (Collector
), scanning at the UI rate (Notifier
)
and notify on appropriate threads.
The second part consists of an expression language that allows to define
how to connect the first set of objects with each other. SourceRateExpression
describes data as it's coming out at the network rate, DesiredRateExpression
defines data at the scanning rate for the UI, and ExpressionLanguage
defines static methods that define the operator in the expression language.
Users can extend both the first part (by extending support for different types, providing different support for different data source or creating new computation elements) and the second part (by extending the language to support other cases. All support for data types is relegated to separate packages: you can use the same style to extend the framework to your needs.
|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |