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,8 +48,9 @@ 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;
boolean connected = false; boolean connected = false;
boolean selected = false; boolean selected = false;
@ -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

@ -1,25 +1,25 @@
/* /*
* Copyright 2015 Alexander Nozik. * Copyright 2015 Alexander Nozik.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
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);
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(); 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")
@ -279,7 +225,7 @@ public class MspViewController implements Initializable, MspListener {
val = Double.NaN; val = Double.NaN;
} }
TimePlottable pl = plottables.get(Integer.toString(entry.getKey())); TimePlottable pl = plottables.get(Integer.toString(entry.getKey()));
if(pl!= null){ if (pl != null) {
pl.put(Value.of(val)); pl.put(Value.of(val));
} }
} }
@ -310,7 +256,7 @@ public class MspViewController implements Initializable, MspListener {
@FXML @FXML
private void onAutoRangeChange(DragEvent event) { private void onAutoRangeChange(DragEvent event) {
plottables.setValue(TimePlottable.MAX_AGE_KEY, this.autoRangeSlider.getValue()*60000); plottables.setValue(TimePlottable.MAX_AGE_KEY, this.autoRangeSlider.getValue() * 60000);
} }
@FXML @FXML
@ -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

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
Copyright 2015 Alexander Nozik. Copyright 2015 Alexander Nozik.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<config> <config>
<device type="msp" name="msp"> <device type="msp" name="msp">
@ -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,19 +15,16 @@ 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 {
@FXML @FXML
ToggleSwitch powerSwitch; ToggleSwitch powerSwitch;
@Override @Override
public Node getComponent() { public Node getComponent() {
if (node == null) { if (node == null) {
@ -41,19 +37,15 @@ public class PoweredVacuumeterView extends VacuumeterView {
} }
} }
return node; return node;
} }
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
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;