use of org.csstudio.display.builder.runtime.pv.RuntimePV in project org.csstudio.display.builder by kasemir.
the class ImageWidgetRuntime method bindROI.
/**
* Bind an ROI PV to an ROI value
* @param name_prop Property for the PV name
* @param value_prop Property for the value
*/
private void bindROI(final WidgetProperty<String> name_prop, final WidgetProperty<Double> value_prop) {
final String pv_name = name_prop.getValue();
if (pv_name.isEmpty())
return;
logger.log(Level.FINER, "Connecting {0} to ROI PV {1}", new Object[] { widget, pv_name });
try {
final RuntimePV pv = PVFactory.getPV(pv_name);
addPV(pv);
roi_pvs.add(pv);
// Write value changes to the PV
final WidgetPropertyListener<Double> prop_listener = (prop, old, value) -> {
try {
if (value == VTypeUtil.getValueNumber(pv.read()).doubleValue())
return;
// System.out.println("Writing " + value_prop + " to PV " + pv_name);
pv.write(value);
} catch (Exception ex) {
logger.log(Level.WARNING, "Error writing ROI value to PV " + pv_name, ex);
}
};
value_prop.addPropertyListener(prop_listener);
roi_prop_listeners.put(value_prop, prop_listener);
// Write PV updates to the value
final RuntimePVListener pv_listener = new RuntimePVListener() {
@Override
public void valueChanged(final RuntimePV pv, final VType value) {
final double number = VTypeUtil.getValueNumber(value).doubleValue();
if (number == value_prop.getValue())
return;
// System.out.println("Writing from PV " + pv_name + " to " + value_prop);
value_prop.setValue(number);
}
};
pv.addListener(pv_listener);
roi_pv_listeners.put(pv, pv_listener);
} catch (Exception ex) {
logger.log(Level.WARNING, "Error connecting ROI PV " + pv_name, ex);
}
}
use of org.csstudio.display.builder.runtime.pv.RuntimePV in project org.csstudio.display.builder by kasemir.
the class ImageWidgetRuntime method stop.
@Override
public void stop() {
// Disconnect ROI PVs and listeners
for (Map.Entry<WidgetProperty<?>, WidgetPropertyListener<?>> entry : roi_prop_listeners.entrySet()) entry.getKey().removePropertyListener(entry.getValue());
roi_prop_listeners.clear();
for (Map.Entry<RuntimePV, RuntimePVListener> entry : roi_pv_listeners.entrySet()) entry.getKey().removeListener(entry.getValue());
roi_pv_listeners.clear();
for (RuntimePV pv : roi_pvs) {
removePV(pv);
PVFactory.releasePV(pv);
}
roi_pvs.clear();
// Disconnect cursor info PV
if (x_pv != null && y_pv != null) {
y_pv.removeListener(cursor_pv_listener);
x_pv.removeListener(cursor_pv_listener);
}
if (unbind(cursor_pv))
widget.runtimePropCursorInfo().removePropertyListener(cursor_info_listener);
boolean x_or_y = unbind(y_pv);
x_or_y |= unbind(x_pv);
if (x_or_y)
widget.runtimePropCrosshair().removePropertyListener(crosshair_listener);
y_pv = x_pv = cursor_pv = null;
super.stop();
}
use of org.csstudio.display.builder.runtime.pv.RuntimePV in project org.csstudio.display.builder by kasemir.
the class XYPlotWidgetRuntime method bindMarker.
private void bindMarker(final WidgetProperty<String> name_prop, final WidgetProperty<Double> value_prop) {
final String pv_name = name_prop.getValue();
if (pv_name.isEmpty())
return;
logger.log(Level.FINER, "Connecting {0} to Marker PV {1}", new Object[] { widget, pv_name });
try {
final RuntimePV pv = PVFactory.getPV(pv_name);
addPV(pv);
marker_pvs.add(pv);
// Write value changes to the PV
final WidgetPropertyListener<Double> prop_listener = (prop, old, value) -> {
// Ignore if PV already has same value to break update loops
double pv_value = VTypeUtil.getValueNumber(pv.read()).doubleValue();
if (value == pv_value)
return;
try {
// System.out.println("Writing " + value_prop + " to PV " + pv_name);
pv.write(value);
} catch (Exception ex) {
logger.log(Level.WARNING, "Error writing marker value to PV " + pv_name, ex);
// Restore property to the unchanged value of the PV
value_prop.setValue(pv_value);
}
};
value_prop.addPropertyListener(prop_listener);
marker_prop_listeners.put(value_prop, prop_listener);
// Write PV updates to the value
final RuntimePVListener pv_listener = new RuntimePVListener() {
@Override
public void valueChanged(final RuntimePV pv, final VType value) {
final double number = VTypeUtil.getValueNumber(value).doubleValue();
if (number == value_prop.getValue())
return;
// System.out.println("Writing " + number + " from PV " + pv_name + " to " + value_prop);
value_prop.setValue(number);
}
};
pv.addListener(pv_listener);
marker_pv_listeners.put(pv, pv_listener);
} catch (Exception ex) {
logger.log(Level.WARNING, "Error connecting Marker PV " + pv_name, ex);
}
}
use of org.csstudio.display.builder.runtime.pv.RuntimePV in project org.csstudio.display.builder by kasemir.
the class WidgetRuntime method start.
/**
* Start: Connect to PVs, start scripts
* @throws Exception on error
*/
public void start() throws Exception {
// Update "value" property from primary PV, if defined
final Optional<WidgetProperty<String>> name = widget.checkProperty(propPVName);
final Optional<WidgetProperty<VType>> value = widget.checkProperty(runtimePropPVValue);
if (name.isPresent() && value.isPresent())
pv_name_binding.set(new PVNameToValueBinding(this, name.get(), value.get(), true));
// Prepare action-related PVs
final List<ActionInfo> actions = widget.propActions().getValue().getActions();
if (actions.size() > 0) {
final List<RuntimePV> action_pvs = new ArrayList<>();
for (final ActionInfo action : actions) {
if (action instanceof WritePVActionInfo) {
final String pv_name = ((WritePVActionInfo) action).getPV();
final String expanded = MacroHandler.replace(widget.getMacrosOrProperties(), pv_name);
final RuntimePV pv = PVFactory.getPV(expanded);
action_pvs.add(pv);
addPV(pv, true);
}
}
if (action_pvs.size() > 0)
this.writable_pvs = action_pvs;
}
widget.propClass().addPropertyListener(update_widget_class);
// Start scripts in pool because Jython setup is expensive
RuntimeUtil.getExecutor().execute(this::startScripts);
}
use of org.csstudio.display.builder.runtime.pv.RuntimePV in project org.csstudio.display.builder by kasemir.
the class ArrayPVDispatcherTest method testScalarPVDispatcher.
/**
* Test double-typed scalar PV
*/
@Test
public void testScalarPVDispatcher() throws Exception {
// Not really an array..
final RuntimePV array_pv = PVFactory.getPV("loc://no_array(3.14)");
// The per-element PVs that will be bound to the array
final AtomicReference<List<RuntimePV>> element_pvs = new AtomicReference<>();
final CountDownLatch got_element_pvs = new CountDownLatch(1);
// Listener to the ArrayPVDispatcher
final Listener dispatch_listener = new Listener() {
@Override
public void arrayChanged(final List<RuntimePV> pvs) {
System.out.println("Per-element PVs: ");
element_pvs.set(pvs);
dump(pvs);
got_element_pvs.countDown();
}
};
final ArrayPVDispatcher dispatcher = new ArrayPVDispatcher(array_pv, "element123456_", dispatch_listener);
// Await initial set of per-element PVs
got_element_pvs.await();
assertThat(element_pvs.get().size(), equalTo(1));
assertThat(VTypeUtil.getValueNumber(element_pvs.get().get(0).read()).doubleValue(), equalTo(3.14));
// Change array -> Observe update of per-element PV
System.out.println("Updating 'array'");
array_pv.write(47.11);
dump(element_pvs.get());
assertThat(VTypeUtil.getValueNumber(element_pvs.get().get(0).read()).doubleValue(), equalTo(47.11));
// Change per-element PV -> Observe update of 'array'
System.out.println("Updating per-element PV for element [2]");
element_pvs.get().get(0).write(11.47);
final Number value = VTypeUtil.getValueNumber(array_pv.read());
System.out.println("'Array': " + value);
assertThat(value, equalTo(11.47));
// Close dispatcher
dispatcher.close();
// Close the array PV
PVFactory.releasePV(array_pv);
}
Aggregations