Working on devices

This commit is contained in:
Alexander Nozik 2017-05-09 22:20:33 +03:00
parent 598c3f0a75
commit 0ebe97b18e
20 changed files with 317 additions and 241 deletions

View File

@ -16,17 +16,12 @@
package inr.numass.cryotemp; package inr.numass.cryotemp;
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Level;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.connections.StorageConnection;
import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.ControlException;
import hep.dataforge.exceptions.StorageException;
import hep.dataforge.io.MetaFileReader; import hep.dataforge.io.MetaFileReader;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaUtils; import hep.dataforge.meta.MetaUtils;
import hep.dataforge.storage.api.Storage;
import hep.dataforge.storage.commons.StorageFactory;
import hep.dataforge.storage.commons.StorageManager; import hep.dataforge.storage.commons.StorageManager;
import inr.numass.client.ClientUtils; import inr.numass.control.NumassConnections;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
@ -40,10 +35,13 @@ import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.text.ParseException; import java.text.ParseException;
import static hep.dataforge.control.devices.PortSensor.PORT_NAME_KEY;
/** /**
* @author darksnake * @author darksnake
*/ */
public class PKT8App extends Application { public class PKT8App extends Application {
public static final String DEFAULT_CONFIG_LOCATION = "numass-devices.xml"; public static final String DEFAULT_CONFIG_LOCATION = "numass-devices.xml";
@ -77,23 +75,11 @@ public class PKT8App extends Application {
device = setupDevice(deviceName, config); device = setupDevice(deviceName, config);
// setting up storage connections // setting up storage connections
if (config.hasMeta("storage")) { NumassConnections.connectStorage(device, config);
String numassRun = ClientUtils.getRunName(config);
config.getMetaList("storage").forEach(node -> {
Storage storage = StorageFactory.buildStorage(device.getContext(), node);
if (!numassRun.isEmpty()) {
try {
storage = storage.buildShelf(numassRun, Meta.empty());
} catch (StorageException e) {
LoggerFactory.getLogger(getClass()).error("Failed to build shelf");
}
}
device.connect(new StorageConnection(storage), Roles.STORAGE_ROLE);
});
}
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Indicator.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Indicator.fxml"));
PKT8Controller controller = new PKT8Controller(device); PKT8Controller controller = new PKT8Controller();
device.connect(controller, "view");
loader.setController(controller); loader.setController(controller);
Parent parent = loader.load(); Parent parent = loader.load();
@ -111,7 +97,6 @@ public class PKT8App extends Application {
Platform.runLater(() -> { Platform.runLater(() -> {
try { try {
device.init(); device.init();
// controller.start();
} catch (ControlException e) { } catch (ControlException e) {
e.printStackTrace(); e.printStackTrace();
throw new RuntimeException(e); throw new RuntimeException(e);
@ -137,10 +122,14 @@ public class PKT8App extends Application {
deviceMeta = config; deviceMeta = config;
} }
PKT8Device device = new PKT8Device(deviceMeta.getString("port", "virtual")); PKT8Device device = new PKT8Device();
device.configure(deviceMeta); device.configure(deviceMeta);
if(!deviceMeta.hasValue(PORT_NAME_KEY)){
device.getLogger().warn("Port name not provided, will try to use emulation port");
}
return device; return device;
} }

View File

@ -1,5 +1,6 @@
package inr.numass.cryotemp; package inr.numass.cryotemp;
import hep.dataforge.control.connections.DeviceConnection;
import hep.dataforge.control.devices.Device; import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener; import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.control.measurements.Measurement; import hep.dataforge.control.measurements.Measurement;
@ -26,11 +27,11 @@ import java.util.ResourceBundle;
/** /**
* Created by darksnake on 07-Oct-16. * Created by darksnake on 07-Oct-16.
*/ */
public class PKT8Controller implements Initializable, DeviceListener, MeasurementListener<PKT8Result> { public class PKT8Controller extends DeviceConnection<PKT8Device> implements Initializable, DeviceListener, MeasurementListener<PKT8Result> {
private final PKT8Device device;
private LogFragment logFragment; private LogFragment logFragment;
private PKT8PlotFragment plotFragment; private PKT8PlotFragment plotFragment;
@FXML @FXML
private ToggleButton startStopButton; private ToggleButton startStopButton;
@FXML @FXML
@ -42,35 +43,28 @@ public class PKT8Controller implements Initializable, DeviceListener, Measuremen
@FXML @FXML
private TableView<PKT8Result> table; private TableView<PKT8Result> table;
@FXML @FXML
private TableColumn<TableView<PKT8Result>, String> sensorColumn; private TableColumn<TableView<PKT8Result>, String> sensorColumn;
@FXML @FXML
private TableColumn<TableView<PKT8Result>, Double> resColumn; private TableColumn<TableView<PKT8Result>, Double> resColumn;
@FXML @FXML
private TableColumn<TableView<PKT8Result>, String> tempColumn; private TableColumn<TableView<PKT8Result>, String> tempColumn;
public PKT8Controller(PKT8Device device) {
this.device = device;
}
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
this.logFragment = new LogFragment(); this.logFragment = new LogFragment();
logFragment.addLogHandler(device.getContext().getLogger()); logFragment.addLogHandler(getDevice().getContext().getLogger());
//TODO to be removed later //TODO to be removed later
logFragment.hookStd(); logFragment.hookStd();
new FragmentWindow(logFragment).bindTo(consoleButton); new FragmentWindow(logFragment).bindTo(consoleButton);
plotFragment = new PKT8PlotFragment(device); plotFragment = new PKT8PlotFragment(getDevice());
new FragmentWindow(plotFragment).bindTo(plotButton); new FragmentWindow(plotFragment).bindTo(plotButton);
sensorColumn.setCellValueFactory(new PropertyValueFactory<>("channel")); sensorColumn.setCellValueFactory(new PropertyValueFactory<>("channel"));
resColumn.setCellValueFactory(new PropertyValueFactory<>("rawString")); resColumn.setCellValueFactory(new PropertyValueFactory<>("rawString"));
tempColumn.setCellValueFactory(new PropertyValueFactory<>("temperatureString")); tempColumn.setCellValueFactory(new PropertyValueFactory<>("temperatureString"));
startStopButton.selectedProperty().setValue(device.isMeasuring()); startStopButton.selectedProperty().setValue(getDevice().isMeasuring());
} }
@Override @Override
@ -100,20 +94,20 @@ public class PKT8Controller implements Initializable, DeviceListener, Measuremen
public void start() throws MeasurementException { public void start() throws MeasurementException {
device.startMeasurement().addListener(this); getDevice().startMeasurement().addListener(this);
} }
public void stop() throws MeasurementException { public void stop() throws MeasurementException {
if (device.isMeasuring()) { if (getDevice().isMeasuring()) {
device.getMeasurement().removeListener(this); getDevice().getMeasurement().removeListener(this);
device.stopMeasurement(false); getDevice().stopMeasurement(false);
} }
} }
@FXML @FXML
private void onStartStopClick(ActionEvent event) { private void onStartStopClick(ActionEvent event) {
if (device != null) { if (getDevice() != null) {
try { try {
if (startStopButton.isSelected()) { if (startStopButton.isSelected()) {
start(); start();
@ -122,7 +116,7 @@ public class PKT8Controller implements Initializable, DeviceListener, Measuremen
stop(); stop();
} }
} catch (ControlException ex) { } catch (ControlException ex) {
evaluateDeviceException(device, "Failed to start or stop device", ex); evaluateDeviceException(getDevice(), "Failed to start or stop device", ex);
} }
} }
} }

View File

@ -15,6 +15,7 @@
*/ */
package inr.numass.cryotemp; package inr.numass.cryotemp;
import hep.dataforge.context.Context;
import hep.dataforge.control.collectors.RegularPointCollector; import hep.dataforge.control.collectors.RegularPointCollector;
import hep.dataforge.control.connections.LoaderConnection; import hep.dataforge.control.connections.LoaderConnection;
import hep.dataforge.control.connections.PointListenerConnection; import hep.dataforge.control.connections.PointListenerConnection;
@ -25,6 +26,7 @@ import hep.dataforge.control.devices.annotations.RoleDef;
import hep.dataforge.control.measurements.AbstractMeasurement; import hep.dataforge.control.measurements.AbstractMeasurement;
import hep.dataforge.control.measurements.Measurement; import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.ports.PortHandler; import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.description.ValueDef;
import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.ControlException;
import hep.dataforge.exceptions.MeasurementException; import hep.dataforge.exceptions.MeasurementException;
import hep.dataforge.exceptions.PortException; import hep.dataforge.exceptions.PortException;
@ -49,7 +51,10 @@ import java.util.stream.Collectors;
*/ */
@RoleDef(name = Roles.STORAGE_ROLE) @RoleDef(name = Roles.STORAGE_ROLE)
@RoleDef(name = Roles.POINT_LISTENER_ROLE) @RoleDef(name = Roles.POINT_LISTENER_ROLE)
@RoleDef(name = Roles.VIEW_ROLE, objectType = PKT8Controller.class)
@ValueDef(name = "port",def = "virtual", info = "The name of the port for this PKT8")
public class PKT8Device extends PortSensor<PKT8Result> { public class PKT8Device extends PortSensor<PKT8Result> {
public static final String PKT8_DEVICE_TYPE = "numass:pkt8";
public static final String PGA = "pga"; public static final String PGA = "pga";
public static final String SPS = "sps"; public static final String SPS = "sps";
@ -61,8 +66,12 @@ public class PKT8Device extends PortSensor<PKT8Result> {
private final Map<String, PKT8Channel> channels = new HashMap<>(); private final Map<String, PKT8Channel> channels = new HashMap<>();
private RegularPointCollector collector; private RegularPointCollector collector;
public PKT8Device(String portName) { public PKT8Device() {
super(portName); }
public PKT8Device(Context context, Meta meta) {
} }
@Override @Override
@ -277,7 +286,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
// setting up the collector // setting up the collector
Duration duration = Duration.parse(meta().getString("averagingDuration", "PT30S")); Duration duration = Duration.parse(meta().getString("averagingDuration", "PT30S"));
collector = new RegularPointCollector((DataPoint dp) -> { collector = new RegularPointCollector((DataPoint dp) -> {
forEachTypedConnection(Roles.POINT_LISTENER_ROLE, PointListener.class, listener -> { forEachConnection(Roles.POINT_LISTENER_ROLE, PointListener.class, listener -> {
getLogger().debug("Point measurement complete. Pushing..."); getLogger().debug("Point measurement complete. Pushing...");
listener.accept(dp); listener.accept(dp);
}); });

View File

@ -0,0 +1,33 @@
package inr.numass.cryotemp;
import hep.dataforge.context.Context;
import hep.dataforge.control.connections.Connection;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.devices.DeviceFactory;
import hep.dataforge.meta.Meta;
import java.util.Objects;
/**
* Created by darksnake on 09-May-17.
*/
public class PKT8DeviceFactory implements DeviceFactory<PKT8Device> {
@Override
public String getType() {
return PKT8Device.PKT8_DEVICE_TYPE;
}
@Override
public PKT8Device build(Context context, Meta meta) {
return new PKT8Device(context, meta);
}
@Override
public Connection<PKT8Device> buildConnection(String role, Context context, Meta meta) {
if(Objects.equals(role, Roles.VIEW_ROLE)){
return new PKT8Controller();
} else {
return DeviceFactory.super.buildConnection(role, context, meta);
}
}
}

View File

@ -48,6 +48,7 @@ import java.util.function.Consumer;
*/ */
@RoleDef(name = Roles.STORAGE_ROLE, objectType = StorageConnection.class) @RoleDef(name = Roles.STORAGE_ROLE, objectType = StorageConnection.class)
public class MspDevice extends SingleMeasurementDevice implements PortHandler.PortController { public class MspDevice extends SingleMeasurementDevice implements PortHandler.PortController {
public static final String MSP_DEVICE_TYPE = "msp";
// private static final String PEAK_SET_PATH = "peakJump.peak"; // private static final String PEAK_SET_PATH = "peakJump.peak";
private static final int TIMEOUT = 200; private static final int TIMEOUT = 200;
@ -81,8 +82,8 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
super.stopMeasurement(true); super.stopMeasurement(true);
setFileamentOn(false); setFileamentOn(false);
setConnected(false); setConnected(false);
handler.unholdBy(this); getHandler().unholdBy(this);
handler.close(); getHandler().close();
} }
@Override @Override
@ -184,7 +185,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
} }
} }
public void setListener(MspListener listener) { public void setMspListener(MspListener listener) {
this.mspListener = listener; this.mspListener = listener;
} }
@ -200,7 +201,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
if (mspListener != null) { if (mspListener != null) {
mspListener.acceptRequest(request); mspListener.acceptRequest(request);
} }
handler.send(request); getHandler().send(request);
} }
/** /**
@ -235,7 +236,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
mspListener.acceptRequest(request); mspListener.acceptRequest(request);
} }
String response = handler.sendAndWait( String response = getHandler().sendAndWait(
request, request,
(String str) -> str.trim().startsWith(commandName), (String str) -> str.trim().startsWith(commandName),
TIMEOUT TIMEOUT
@ -305,7 +306,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
updateState("filamentOn", status.equals("ON")); updateState("filamentOn", status.equals("ON"));
updateState("filamentStatus", status); updateState("filamentStatus", status);
if (mspListener != null) { if (mspListener != null) {
mspListener.acceptFillamentStateChange(status); mspListener.acceptFilamentStateChange(status);
} }
break; break;
} }
@ -325,6 +326,13 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
} }
} }
private TcpPortHandler getHandler() {
if(handler == null){
throw new RuntimeException("Device not initialized");
}
return handler;
}
/** /**
* The MKS response as two-dimensional array of strings * The MKS response as two-dimensional array of strings
*/ */
@ -504,7 +512,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
if (isFilamentOn()) { if (isFilamentOn()) {
mspListener.acceptScan(measurement); mspListener.acceptScan(measurement);
forEachTypedConnection(Roles.STORAGE_ROLE, StorageConnection.class, (StorageConnection connection) -> { forEachConnection(Roles.STORAGE_ROLE, StorageConnection.class, (StorageConnection connection) -> {
PointLoader pl = loaderMap.computeIfAbsent(connection, con -> makeLoader(con)); PointLoader pl = loaderMap.computeIfAbsent(connection, con -> makeLoader(con));
try { try {
pl.push(point.build()); pl.push(point.build());

View File

@ -0,0 +1,23 @@
package inr.numass.control.msp;
import hep.dataforge.context.Context;
import hep.dataforge.control.devices.DeviceFactory;
import hep.dataforge.meta.Meta;
/**
* Created by darksnake on 09-May-17.
*/
public class MspDeviceFactory implements DeviceFactory<MspDevice> {
@Override
public String getType() {
return MspDevice.MSP_DEVICE_TYPE;
}
@Override
public MspDevice build(Context context, Meta config) {
MspDevice device = new MspDevice();
device.setContext(context);
device.configure(config);
return device;
}
}

View File

@ -30,7 +30,7 @@ public interface MspListener {
void acceptMessage(String message); void acceptMessage(String message);
void acceptRequest(String message); void acceptRequest(String message);
default void acceptFillamentStateChange(String fillamentState){ default void acceptFilamentStateChange(String fillamentState){
} }
} }

View File

@ -16,10 +16,10 @@
package inr.numass.control.msp; package inr.numass.control.msp;
import hep.dataforge.exceptions.PortException; import hep.dataforge.exceptions.PortException;
import java.io.IOException; import java.io.IOException;
/** /**
*
* @author darksnake * @author darksnake
*/ */
public class MspTest { public class MspTest {

View File

@ -17,11 +17,16 @@ package inr.numass.control.msp.fx;
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Level;
import hep.dataforge.context.Global; import hep.dataforge.context.Global;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.io.MetaFileReader; import hep.dataforge.io.MetaFileReader;
import hep.dataforge.io.XMLMetaReader; import hep.dataforge.io.XMLMetaReader;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.storage.commons.StorageManager; import hep.dataforge.storage.commons.StorageManager;
import inr.numass.control.msp.MspDevice;
import inr.numass.control.msp.MspDeviceFactory;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
@ -31,13 +36,16 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.Locale; import java.util.Locale;
import static inr.numass.control.msp.MspDevice.MSP_DEVICE_TYPE;
/** /**
*
* @author darksnake * @author darksnake
*/ */
public class MspApp extends Application { public class MspApp extends Application {
public static final String DEFAULT_CONFIG_LOCATION = "msp-config.xml";
private MspDevice device;
MspViewController controller;
/** /**
* @param args the command line arguments * @param args the command line arguments
@ -55,41 +63,67 @@ public class MspApp extends Application {
String configFileName = getParameters().getNamed().get("config"); String configFileName = getParameters().getNamed().get("config");
if (configFileName == null) { if (configFileName == null) {
configFileName = "msp-config.xml"; configFileName = DEFAULT_CONFIG_LOCATION;
} }
File configFile = new File(configFileName); File configFile = new File(configFileName);
Meta config; Meta config;
if (configFile.exists()) { if (configFile.exists()) {
config = MetaFileReader.read(configFile).build(); config = MetaFileReader.read(configFile).build();
} else { } else {
// throw new RuntimeException("Configuration file not found"); config = new XMLMetaReader().read(getClass().getResourceAsStream("/config/msp-config.xml"));
config = new XMLMetaReader().read(MspApp.class.getClassLoader().getResourceAsStream("config/msp-config.xml"), -1);
} }
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/MspView.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/MspView.fxml"));
Parent parent = loader.load(); Parent parent = loader.load();
controller = loader.getController(); MspViewController controller = loader.getController();
controller.setDeviceConfig(Global.instance(), config); Scene scene = new Scene(parent, 800, 600);
Scene scene = new Scene(parent, 600, 400);
primaryStage.setTitle("Numass mass-spectrometer view"); primaryStage.setTitle("Numass mass-spectrometer view");
primaryStage.setScene(scene); primaryStage.setScene(scene);
primaryStage.setMinHeight(400); primaryStage.setMinHeight(400);
primaryStage.setMinWidth(600); primaryStage.setMinWidth(600);
// primaryStage.setResizable(false);
primaryStage.show();
Platform.runLater(()->{
try {
device = new MspDeviceFactory().build(Global.instance(), getMspConfig(config));
device.init();
device.connect(controller, Roles.VIEW_ROLE);
} catch (ControlException e) {
throw new RuntimeException("Failed to build device", e);
} }
});
primaryStage.show();
}
private Meta getMspConfig(Meta config) {
Meta mspConfig = null;
if (config.hasMeta("device")) {
for (Meta d : config.getMetaList("device")) {
if (d.getString("type", "unknown").equals(MSP_DEVICE_TYPE)) {
mspConfig = d;
}
}
} else if (config.hasMeta("peakJump")) {
mspConfig = config;
}
return mspConfig;
}
// showError(String.format("Can't connect to %s:%d. The port is either busy or not the MKS mass-spectrometer port",
// device.meta().getString("connection.ip", "127.0.0.1"),
// device.meta().getInt("connection.port", 10014)));
// throw new RuntimeException("Can't connect to device");
@Override @Override
public void stop() throws Exception { public void stop() throws Exception {
super.stop(); super.stop();
controller.shutdown(); if (device != null) {
// System.exit(0); device.shutdown();
}
} }
} }

View File

@ -15,16 +15,16 @@
*/ */
package inr.numass.control.msp.fx; package inr.numass.control.msp.fx;
import hep.dataforge.context.Context; import hep.dataforge.control.connections.DeviceConnection;
import hep.dataforge.context.Global;
import hep.dataforge.control.connections.Roles; import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.connections.StorageConnection; import hep.dataforge.control.connections.StorageConnection;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.ControlException;
import hep.dataforge.exceptions.PortException; import hep.dataforge.exceptions.PortException;
import hep.dataforge.exceptions.StorageException; import hep.dataforge.exceptions.StorageException;
import hep.dataforge.fx.fragments.FragmentWindow; import hep.dataforge.fx.fragments.FragmentWindow;
import hep.dataforge.fx.fragments.LogFragment; import hep.dataforge.fx.fragments.LogFragment;
import hep.dataforge.io.MetaFileReader;
import hep.dataforge.meta.ConfigChangeListener; import hep.dataforge.meta.ConfigChangeListener;
import hep.dataforge.meta.Configuration; import hep.dataforge.meta.Configuration;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
@ -59,10 +59,7 @@ import org.controlsfx.control.ToggleSwitch;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.text.ParseException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@ -72,18 +69,14 @@ import java.util.ResourceBundle;
* *
* @author darksnake * @author darksnake
*/ */
public class MspViewController implements Initializable, MspListener { public class MspViewController extends DeviceConnection<MspDevice> implements DeviceListener, Initializable, MspListener {
public static final String MSP_DEVICE_TYPE = "msp";
public static final String DEFAULT_CONFIG_LOCATION = "msp-config.xml";
private final PlottableGroup<TimePlottable> plottables = new PlottableGroup<>(); private final PlottableGroup<TimePlottable> plottables = new PlottableGroup<>();
private final String mspName = "msp";
private MspDevice device;
private Configuration viewConfig; private Configuration viewConfig;
private JFreeChartFrame plot; private JFreeChartFrame plot;
private LogFragment logArea; private LogFragment logArea;
private StorageConnection connection; private StorageConnection connection;
@FXML @FXML
private Slider autoRangeSlider; private Slider autoRangeSlider;
@FXML @FXML
@ -128,7 +121,7 @@ public class MspViewController implements Initializable, MspListener {
fillamentSelector.setConverter(new StringConverter<Integer>() { fillamentSelector.setConverter(new StringConverter<Integer>() {
@Override @Override
public String toString(Integer object) { public String toString(Integer object) {
return "Fillament " + object; return "Filament " + object;
} }
@Override @Override
@ -143,7 +136,7 @@ public class MspViewController implements Initializable, MspListener {
fillamentSelector.setDisable(newValue); fillamentSelector.setDisable(newValue);
getDevice().setFileamentOn(newValue); getDevice().setFileamentOn(newValue);
} catch (PortException ex) { } catch (PortException ex) {
device.getLogger().error("Failed to toggle fillaments"); getDevice().getLogger().error("Failed to toggle filaments");
} }
}); });
} }
@ -162,69 +155,22 @@ public class MspViewController implements Initializable, MspListener {
this.viewConfig.addObserver(viewConfigObserver); this.viewConfig.addObserver(viewConfigObserver);
} }
private MspDevice getDevice() { @Override
if (this.device == null) { public void open(MspDevice device) throws Exception {
showError("Device configuration not found. Using default configuration."); super.open(device);
Meta defaultDeviceConfig; getDevice().setMspListener(this);
try { device.getConfig().optMeta("plot").ifPresent(this::setViewConfig);
defaultDeviceConfig = MetaFileReader
.read(new File(getClass().getResource("/config/msp-config.xml").toURI()));
} catch (IOException | URISyntaxException | ParseException ex) {
throw new Error(ex);
}
setDeviceConfig(Global.instance(), defaultDeviceConfig);
}
return device;
}
public void setDeviceConfig(Context context, Meta config) {
Meta mspConfig = null;
if (config.hasMeta("device")) {
for (Meta d : config.getMetaList("device")) {
if (d.getString("type", "unknown").equals(MSP_DEVICE_TYPE)
&& d.getString("name", "msp").equals(this.mspName)) {
mspConfig = d;
}
}
} else if (config.hasMeta("peakJump")) {
mspConfig = config;
}
if (mspConfig != null) {
this.device = new MspDevice();
device.setName(mspName);
device.setContext(context);
device.configure(mspConfig);
try {
getDevice().setListener(this);
getDevice().init();
} catch (ControlException ex) {
showError(String.format("Can't connect to %s:%d. The port is either busy or not the MKS mass-spectrometer port",
device.meta().getString("connection.ip", "127.0.0.1"),
device.meta().getInt("connection.port", 10014)));
throw new RuntimeException("Can't connect to device");
}
} else {
showError("Can't find device description in given confgiuration");
throw new RuntimeException();
}
if (config.hasMeta("plots.msp")) {
setViewConfig(config.getMeta("plots.msp"));
}
updatePlot(); updatePlot();
} }
public void setDeviceConfig(Context context, File cfgFile) { // public void setDeviceConfig(Context context, File cfgFile) {
try { // try {
Meta deviceConfig = MetaFileReader.instance().read(context, cfgFile, null); // Meta deviceConfig = MetaFileReader.instance().read(context, cfgFile, null);
setDeviceConfig(context, deviceConfig); // setDeviceConfig(context, deviceConfig);
} catch (IOException | ParseException ex) { // } catch (IOException | ParseException ex) {
showError("Can't load configuration file"); // showError("Can't load configuration file");
} // }
} // }
public void initPlot() { public void initPlot() {
Meta plotConfig = new MetaBuilder("plotFrame") Meta plotConfig = new MetaBuilder("plotFrame")
@ -335,12 +281,8 @@ public class MspViewController implements Initializable, MspListener {
} }
public void shutdown() throws IOException, ControlException {
getDevice().shutdown();
}
@Override @Override
public void acceptFillamentStateChange(String fillamentState) { public void acceptFilamentStateChange(String fillamentState) {
Platform.runLater(() -> { Platform.runLater(() -> {
switch (fillamentState) { switch (fillamentState) {
case "ON": case "ON":
@ -362,32 +304,32 @@ public class MspViewController implements Initializable, MspListener {
private void onStoreButtonClick(ActionEvent event) { private void onStoreButtonClick(ActionEvent event) {
if (storeButton.isSelected()) { if (storeButton.isSelected()) {
if (!device.meta().hasMeta("storage")) { if (!getDevice().meta().hasMeta("storage")) {
device.getLogger().info("Storage not defined. Starting storage selection dialog"); getDevice().getLogger().info("Storage not defined. Starting storage selection dialog");
DirectoryChooser chooser = new DirectoryChooser(); DirectoryChooser chooser = new DirectoryChooser();
File storageDir = chooser.showDialog(this.plotPane.getScene().getWindow()); File storageDir = chooser.showDialog(this.plotPane.getScene().getWindow());
if (storageDir == null) { if (storageDir == null) {
storeButton.setSelected(false); storeButton.setSelected(false);
throw new RuntimeException("User canceled directory selection"); throw new RuntimeException("User canceled directory selection");
} }
device.getConfig().putNode(new MetaBuilder("storage") getDevice().getConfig().putNode(new MetaBuilder("storage")
.putValue("path", storageDir.getAbsolutePath())); .putValue("path", storageDir.getAbsolutePath()));
} }
Meta storageConfig = device.meta().getMeta("storage"); Meta storageConfig = getDevice().meta().getMeta("storage");
Storage localStorage = StorageManager.buildFrom(device.getContext()) Storage localStorage = StorageManager.buildFrom(getDevice().getContext())
.buildStorage(storageConfig); .buildStorage(storageConfig);
String runName = device.meta().getString("numass.run", ""); String runName = getDevice().meta().getString("numass.run", "");
Meta meta = device.meta(); Meta meta = getDevice().meta();
if (meta.hasMeta("numass")) { if (meta.hasMeta("numass")) {
try { try {
device.getLogger().info("Obtaining run information from cetral server..."); getDevice().getLogger().info("Obtaining run information from cetral server...");
NumassClient client = new NumassClient(meta.getString("numass.ip", "192.168.111.1"), NumassClient client = new NumassClient(meta.getString("numass.ip", "192.168.111.1"),
meta.getInt("numass.port", 8335)); meta.getInt("numass.port", 8335));
runName = client.getCurrentRun().getString("path", ""); runName = client.getCurrentRun().getString("path", "");
device.getLogger().info("Run name is '{}'", runName); getDevice().getLogger().info("Run name is '{}'", runName);
} catch (Exception ex) { } catch (Exception ex) {
device.getLogger().warn("Failed to download current run information", ex); getDevice().getLogger().warn("Failed to download current run information", ex);
} }
} }
@ -395,15 +337,39 @@ public class MspViewController implements Initializable, MspListener {
try { try {
localStorage = localStorage.buildShelf(runName, null); localStorage = localStorage.buildShelf(runName, null);
} catch (StorageException ex) { } catch (StorageException ex) {
device.getLogger().error("Failed to create storage shelf. Using root storage instead"); getDevice().getLogger().error("Failed to create storage shelf. Using root storage instead");
} }
} }
connection = new StorageConnection(localStorage); connection = new StorageConnection(localStorage);
device.connect(connection, Roles.STORAGE_ROLE); getDevice().connect(connection, Roles.STORAGE_ROLE);
} else if (connection != null) { } else if (connection != null) {
device.disconnect(connection); getDevice().disconnect(connection);
} }
} }
@Override
public void notifyDeviceInitialized(Device device) {
}
@Override
public void notifyDeviceShutdown(Device device) {
}
@Override
public void notifyDeviceStateChanged(Device device, String name, Value state) {
}
@Override
public void notifyDeviceConfigChanged(Device device) {
}
@Override
public void evaluateDeviceException(Device device, String message, Throwable exception) {
}
} }

View File

@ -30,15 +30,13 @@ limitations under the License.
<peak mass="28"/> <peak mass="28"/>
<peak mass="32"/> <peak mass="32"/>
</peakJump> </peakJump>
</device> <plot>
<plots>
<msp>
<peakJump> <peakJump>
<line mass="2" title="hydrogen" color="black" thickness="6"/> <line mass="2" title="hydrogen" color="black" thickness="6"/>
<line mass="6" title="tritium" thickness="4"/> <line mass="6" title="tritium" thickness="4"/>
<line mass="18" title="water" /> <line mass="18" title="water" />
<line mass="32" title="oxygen"/> <line mass="32" title="oxygen"/>
</peakJump> </peakJump>
</msp> </plot>
</plots> </device>
</config> </config>

View File

@ -0,0 +1,40 @@
package inr.numass.control;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.connections.StorageConnection;
import hep.dataforge.control.devices.Device;
import hep.dataforge.exceptions.StorageException;
import hep.dataforge.meta.Meta;
import hep.dataforge.storage.api.Storage;
import hep.dataforge.storage.commons.StorageFactory;
import inr.numass.client.ClientUtils;
/**
* Created by darksnake on 08-May-17.
*/
public class NumassConnections {
/**
* Create a single or multiple storage connections for a device
* @param device
* @param config
*/
public static void connectStorage(Device device, Meta config) {
//TODO add on reset listener
if (config.hasMeta("storage")) {
String numassRun = ClientUtils.getRunName(config);
config.getMetaList("storage").forEach(node -> {
Storage storage = StorageFactory.buildStorage(device.getContext(), node);
if (!numassRun.isEmpty()) {
try {
storage = storage.buildShelf(numassRun, Meta.empty());
} catch (StorageException e) {
device.getContext().getLogger().error("Failed to build shelf", e);
}
}
device.connect(new StorageConnection(storage), Roles.STORAGE_ROLE);
});
}
}
}

View File

@ -9,6 +9,7 @@ import hep.dataforge.control.measurements.Sensor;
import hep.dataforge.exceptions.StorageException; import hep.dataforge.exceptions.StorageException;
import hep.dataforge.io.MetaFileReader; import hep.dataforge.io.MetaFileReader;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaBuilder;
import hep.dataforge.storage.api.PointLoader; import hep.dataforge.storage.api.PointLoader;
import hep.dataforge.storage.api.Storage; import hep.dataforge.storage.api.Storage;
import hep.dataforge.storage.commons.LoaderFactory; import hep.dataforge.storage.commons.LoaderFactory;
@ -27,7 +28,6 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
/** /**
*
* @author Alexander Nozik * @author Alexander Nozik
*/ */
public class ReadVac extends Application { public class ReadVac extends Application {
@ -56,20 +56,25 @@ public class ReadVac extends Application {
config = Meta.empty(); config = Meta.empty();
} }
Sensor<Double> p1 = new MKSVacDevice(config.getString("p1.port", "com::/dev/ttyUSB0")); Sensor<Double> p1 = new MKSVacDevice();
p1.configure(config.getMeta("p1", Meta.empty())); p1.configure(config.getMeta("p1",
() -> new MetaBuilder("p1").setValue("port", "com::/dev/ttyUSB0")));
p1.setName(config.getString("p1.name", "P1")); p1.setName(config.getString("p1.name", "P1"));
Sensor<Double> p2 = new CM32Device(config.getString("p2.port", "tcp::192.168.111.32:4002")); Sensor<Double> p2 = new CM32Device();
p2.configure(config.getMeta("p2", Meta.empty())); p2.configure(config.getMeta("p2",
() -> new MetaBuilder("p2").setValue("port", "tcp::192.168.111.32:4002")));
p2.setName(config.getString("p2.name", "P2")); p2.setName(config.getString("p2.name", "P2"));
Sensor<Double> p3 = new CM32Device(config.getString("p3.port", "tcp::192.168.111.32:4003")); Sensor<Double> p3 = new CM32Device();
p3.configure(config.getMeta("p3", Meta.empty())); p3.configure(config.getMeta("p3",
() -> new MetaBuilder("p3").setValue("port", "tcp::192.168.111.32:4003")));
p3.setName(config.getString("p3.name", "P3")); p3.setName(config.getString("p3.name", "P3"));
Sensor<Double> px = new VITVacDevice(config.getString("px.port", "com::/dev/ttyUSB1")); Sensor<Double> px = new VITVacDevice();
px.configure(config.getMeta("px", Meta.empty())); px.configure(config.getMeta("px",
() -> new MetaBuilder("px").setValue("port", "tcp::192.168.111.32:4003")));
px.setName(config.getString("px.name", "Px")); px.setName(config.getString("px.name", "Px"));
Sensor<Double> baratron = new MKSBaratronDevice(config.getString("baratron.port", "tcp::192.168.111.33:4004")); Sensor<Double> baratron = new MKSBaratronDevice();
baratron.configure(config.getMeta("baratron", Meta.empty())); baratron.configure(config.getMeta("baratron",
() -> new MetaBuilder("baratron").setValue("port", "tcp::192.168.111.33:4004")));
baratron.setName(config.getString("baratron.name", "Baratron")); baratron.setName(config.getString("baratron.name", "Baratron"));
VacCollectorDevice collector = new VacCollectorDevice(); VacCollectorDevice collector = new VacCollectorDevice();

View File

@ -23,10 +23,6 @@ import hep.dataforge.exceptions.ControlException;
@ValueDef(name = "timeout") @ValueDef(name = "timeout")
public class CM32Device extends PortSensor<Double> { public class CM32Device extends PortSensor<Double> {
public CM32Device(String portName) {
super(portName);
}
@Override @Override
protected PortHandler buildHandler(String portName) throws ControlException { protected PortHandler buildHandler(String portName) throws ControlException {
getLogger().info("Connecting to port {}", portName); getLogger().info("Connecting to port {}", portName);

View File

@ -6,7 +6,6 @@
package inr.numass.readvac.devices; package inr.numass.readvac.devices;
import hep.dataforge.control.devices.PortSensor; import hep.dataforge.control.devices.PortSensor;
import static hep.dataforge.control.devices.PortSensor.CONNECTION_STATE;
import hep.dataforge.control.measurements.Measurement; import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.SimpleMeasurement; import hep.dataforge.control.measurements.SimpleMeasurement;
import hep.dataforge.control.ports.PortHandler; import hep.dataforge.control.ports.PortHandler;
@ -20,9 +19,6 @@ import hep.dataforge.exceptions.ControlException;
@ValueDef(name = "channel") @ValueDef(name = "channel")
public class MKSBaratronDevice extends PortSensor<Double> { public class MKSBaratronDevice extends PortSensor<Double> {
public MKSBaratronDevice(String portName) {
super(portName);
}
@Override @Override
protected Measurement<Double> createMeasurement() { protected Measurement<Double> createMeasurement() {

View File

@ -26,11 +26,6 @@ import java.util.regex.Pattern;
@ValueDef(name = "powerButton", type = "BOOLEAN", def = "true") @ValueDef(name = "powerButton", type = "BOOLEAN", def = "true")
public class MKSVacDevice extends PortSensor<Double> { public class MKSVacDevice extends PortSensor<Double> {
public MKSVacDevice(String portName) {
super(portName);
super.getConfig().setValue("powerButton", true);
}
private String talk(String requestContent) throws ControlException { private String talk(String requestContent) throws ControlException {
String answer = getHandler().sendAndWait(String.format("@%s%s;FF", getDeviceAddress(), requestContent), timeout()); String answer = getHandler().sendAndWait(String.format("@%s%s;FF", getDeviceAddress(), requestContent), timeout());

View File

@ -22,10 +22,6 @@ import java.util.regex.Pattern;
*/ */
public class VITVacDevice extends PortSensor<Double> { public class VITVacDevice extends PortSensor<Double> {
public VITVacDevice(String portName) {
super(portName);
}
@Override @Override
protected PortHandler buildHandler(String portName) throws ControlException { protected PortHandler buildHandler(String portName) throws ControlException {
PortHandler newHandler = super.buildHandler(portName); PortHandler newHandler = super.buildHandler(portName);

View File

@ -128,7 +128,7 @@ public class VacCollectorDevice extends Sensor<DataPoint> {
@Override @Override
protected synchronized void result(DataPoint result, Instant time) { protected synchronized void result(DataPoint result, Instant time) {
super.result(result, time); super.result(result, time);
forEachTypedConnection(Roles.STORAGE_ROLE, PointListener.class, (PointListener listener) -> { forEachConnection(Roles.STORAGE_ROLE, PointListener.class, (PointListener listener) -> {
listener.accept(result); listener.accept(result);
}); });
} }

View File

@ -5,7 +5,6 @@
*/ */
package inr.numass.readvac.fx; package inr.numass.readvac.fx;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.values.Value; import hep.dataforge.values.Value;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -16,11 +15,8 @@ import org.controlsfx.control.ToggleSwitch;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
*
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a> * @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
*/ */
public class PoweredVacuumeterView extends VacuumeterView { public class PoweredVacuumeterView extends VacuumeterView {
@ -48,11 +44,7 @@ public class PoweredVacuumeterView extends VacuumeterView {
unitLabel.setText(getDevice().meta().getString("units", "mbar")); unitLabel.setText(getDevice().meta().getString("units", "mbar"));
deviceNameLabel.setText(getDevice().getName()); deviceNameLabel.setText(getDevice().getName());
powerSwitch.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> { powerSwitch.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
try { getDevice().setState("power", Value.of(newValue));
getDevice().command("setPower", Value.of(newValue));
} catch (ControlException ex) {
Logger.getLogger(PoweredVacuumeterView.class.getName()).log(Level.SEVERE, null, ex);
}
}); });
} }

View File

@ -5,8 +5,10 @@
*/ */
package inr.numass.readvac.fx; package inr.numass.readvac.fx;
import hep.dataforge.control.connections.DeviceViewController; import hep.dataforge.control.connections.DeviceConnection;
import hep.dataforge.control.connections.MeasurementConsumer;
import hep.dataforge.control.devices.Device; import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.control.measurements.Measurement; import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.MeasurementListener; import hep.dataforge.control.measurements.MeasurementListener;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
@ -35,7 +37,7 @@ import java.util.ResourceBundle;
/** /**
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a> * @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
*/ */
public class VacuumeterView extends DeviceViewController implements MeasurementListener<Double>, Initializable, Named, Metoid { public class VacuumeterView extends DeviceConnection implements DeviceListener, MeasurementConsumer, MeasurementListener<Double>, Initializable, Named, Metoid {
private static final DecimalFormat FORMAT = new DecimalFormat("0.###E0"); private static final DecimalFormat FORMAT = new DecimalFormat("0.###E0");
private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ISO_LOCAL_TIME; private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ISO_LOCAL_TIME;