[no commit message]
This commit is contained in:
parent
0c0d9f2aa4
commit
9a9a0beca4
@ -1,6 +1,6 @@
|
||||
apply plugin: 'application'
|
||||
|
||||
version = "0.2.4"
|
||||
version = "0.3.0"
|
||||
|
||||
if (!hasProperty('mainClass')) {
|
||||
ext.mainClass = 'inr.numass.control.msp.fx.MspApp'
|
||||
@ -9,9 +9,7 @@ mainClassName = mainClass
|
||||
|
||||
|
||||
dependencies {
|
||||
compile 'ch.qos.logback:logback-classic:1.1.0+'
|
||||
compile 'org.scream3r:jssc:2.8.0'
|
||||
compile project(':numass-storage:numass-client')
|
||||
compile project(':dataforge-plots')
|
||||
compile project(':dataforge-storage')
|
||||
compile project(':dataforge-control')
|
||||
}
|
4
numass-control/msp/private/cache/retriever/catalog.xml
vendored
Normal file
4
numass-control/msp/private/cache/retriever/catalog.xml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
|
||||
<system systemId="http://javafx.com/javafx/8.0.65" uri="www.oracle.com/technetwork/java/javase/overview/index.html"/>
|
||||
</catalog>
|
1086
numass-control/msp/private/cache/retriever/www.oracle.com/technetwork/java/javase/overview/index.html
vendored
Normal file
1086
numass-control/msp/private/cache/retriever/www.oracle.com/technetwork/java/javase/overview/index.html
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -23,8 +23,6 @@ import hep.dataforge.control.measurements.AbstractMeasurement;
|
||||
import hep.dataforge.control.measurements.Measurement;
|
||||
import hep.dataforge.control.ports.PortHandler;
|
||||
import hep.dataforge.control.ports.TcpPortHandler;
|
||||
import hep.dataforge.points.Format;
|
||||
import hep.dataforge.points.FormatBuilder;
|
||||
import hep.dataforge.points.DataPoint;
|
||||
import hep.dataforge.points.MapPoint;
|
||||
import hep.dataforge.exceptions.ControlException;
|
||||
@ -32,12 +30,15 @@ import hep.dataforge.exceptions.MeasurementException;
|
||||
import hep.dataforge.exceptions.PortException;
|
||||
import hep.dataforge.exceptions.StorageException;
|
||||
import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.points.Format;
|
||||
import hep.dataforge.points.FormatBuilder;
|
||||
import hep.dataforge.storage.api.PointLoader;
|
||||
import hep.dataforge.storage.api.Storage;
|
||||
import hep.dataforge.storage.commons.LoaderFactory;
|
||||
import hep.dataforge.values.Value;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -49,7 +50,7 @@ import java.util.function.Consumer;
|
||||
*
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
@RoleDef(name = Roles.STORAGE_ROLE)
|
||||
@RoleDef(name = Roles.STORAGE_ROLE, objectType = StorageConnection.class)
|
||||
public class MspDevice extends SingleMeasurementDevice implements PortHandler.PortController {
|
||||
|
||||
// private static final String PEAK_SET_PATH = "peakJump.peak";
|
||||
@ -63,6 +64,10 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
private Consumer<MspResponse> responseDelegate;
|
||||
private Consumer<Throwable> errorDelegate;
|
||||
|
||||
boolean connected = false;
|
||||
boolean selected = false;
|
||||
boolean controlled = false;
|
||||
|
||||
// public MspDevice(String name, Context context, Meta config) {
|
||||
// super(name, context, config);
|
||||
// }
|
||||
@ -159,7 +164,8 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
|
||||
response = sendAndWait("Select", sensorName);
|
||||
if (response.isOK()) {
|
||||
updateState("selected", true);
|
||||
selected = true;
|
||||
// updateState("selected", true);
|
||||
} else {
|
||||
error(response.errorDescription(), null);
|
||||
return false;
|
||||
@ -167,12 +173,15 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
|
||||
response = sendAndWait("Control", "inr.numass.msp", "1.0");
|
||||
if (response.isOK()) {
|
||||
updateState("controlled", true);
|
||||
controlled = true;
|
||||
// invalidateState("controlled");
|
||||
// updateState("controlled", true);
|
||||
} else {
|
||||
error(response.errorDescription(), null);
|
||||
return false;
|
||||
}
|
||||
updateState("connected", true);
|
||||
connected = true;
|
||||
// updateState("connected", true);
|
||||
return true;
|
||||
} else {
|
||||
return !sendAndWait("Release").isOK();
|
||||
@ -243,21 +252,28 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return getState("connected") != null && getState("connected").booleanValue();
|
||||
return connected;
|
||||
//return getState("connected") != null && getState("connected").booleanValue();
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return getState("selected") != null && getState("selected").booleanValue();
|
||||
return selected;
|
||||
//return getState("selected") != null && getState("selected").booleanValue();
|
||||
}
|
||||
|
||||
public boolean isControlled() {
|
||||
return getState("controlled") != null && getState("controlled").booleanValue();
|
||||
return controlled;
|
||||
//return getState("controlled") != null && getState("controlled").booleanValue();
|
||||
}
|
||||
|
||||
public boolean isFilamentOn() {
|
||||
return getState("filamentOn").booleanValue();
|
||||
}
|
||||
|
||||
public void selectFillament(int fillament) throws PortException {
|
||||
sendAndWait("FilamentSelect", fillament);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn filament on or off
|
||||
*
|
||||
@ -372,41 +388,39 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
|
||||
private final Map<Integer, Double> measurement = new ConcurrentSkipListMap<>();
|
||||
private Map<Integer, String> peakMap;
|
||||
private List<PointLoader> loaders = new ArrayList<>();
|
||||
private final Map<StorageConnection, PointLoader> loaderMap = new HashMap<>();
|
||||
// private List<PointLoader> loaders = new ArrayList<>();
|
||||
private final Meta meta;
|
||||
private double zero = 0;
|
||||
|
||||
public PeakJumpMeasurement(Meta meta) {
|
||||
this.meta = meta;
|
||||
}
|
||||
|
||||
private void prepareLoaders() {
|
||||
loaders = new ArrayList<>();
|
||||
forEachTypedConnection(Roles.STORAGE_ROLE, StorageConnection.class, (StorageConnection con) -> {
|
||||
try {
|
||||
Storage storage = con.getStorage();
|
||||
private PointLoader makeLoader(StorageConnection connection) {
|
||||
|
||||
if (peakMap == null) {
|
||||
throw new IllegalStateException("Peak map is not initialized");
|
||||
}
|
||||
try {
|
||||
Storage storage = connection.getStorage();
|
||||
|
||||
FormatBuilder builder = new FormatBuilder().addTime("timestamp");
|
||||
for (String peakName : this.peakMap.values()) {
|
||||
builder.addNumber(peakName);
|
||||
}
|
||||
|
||||
Format format = builder.build();
|
||||
|
||||
//TODO Переделать!!!
|
||||
String run = meta().getString("storage.run", "");
|
||||
|
||||
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
|
||||
PointLoader loader = LoaderFactory
|
||||
.buildPointLoder(storage, "msp" + suffix, run, "timestamp", format);
|
||||
loaders.add(loader);
|
||||
} catch (StorageException ex) {
|
||||
getLogger().error("Failed to initialize peak jump loader", ex);
|
||||
if (peakMap == null) {
|
||||
throw new IllegalStateException("Peak map is not initialized");
|
||||
}
|
||||
});
|
||||
|
||||
FormatBuilder builder = new FormatBuilder().addTime("timestamp");
|
||||
this.peakMap.values().stream().forEach((peakName) -> {
|
||||
builder.addNumber(peakName);
|
||||
});
|
||||
|
||||
Format format = builder.build();
|
||||
|
||||
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
|
||||
PointLoader loader = LoaderFactory
|
||||
.buildPointLoder(storage, "msp" + suffix, "", "timestamp", format);
|
||||
return loader;
|
||||
} catch (StorageException ex) {
|
||||
getLogger().error("Failed to create Loader", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -427,7 +441,6 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
throw new ControlException("Can't add mass to measurement measurement for msp");
|
||||
}
|
||||
}
|
||||
prepareLoaders();
|
||||
} else {
|
||||
throw new ControlException("Can't create measurement for msp");
|
||||
}
|
||||
@ -454,6 +467,13 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
boolean stop = sendAndWait("ScanStop").isOK();
|
||||
afterStop();
|
||||
responseDelegate = null;
|
||||
loaderMap.values().forEach(loader -> {
|
||||
try {
|
||||
loader.close();
|
||||
} catch (Exception ex) {
|
||||
getLogger().error("Failed to close Loader", ex);
|
||||
}
|
||||
});
|
||||
return stop;
|
||||
} catch (PortException ex) {
|
||||
throw new MeasurementException(ex);
|
||||
@ -468,9 +488,11 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
switch (response.getCommandName()) {
|
||||
case "MassReading":
|
||||
double mass = Double.parseDouble(response.get(0, 1));
|
||||
double value = Double.parseDouble(response.get(0, 2));
|
||||
double value = Double.parseDouble(response.get(0, 2)) / 100d;
|
||||
measurement.put((int) Math.floor(mass + 0.5), value);
|
||||
break;
|
||||
case "ZeroReading":
|
||||
zero = Double.parseDouble(response.get(0, 2)) / 100d;
|
||||
case "StartingScan":
|
||||
if (mspListener != null && !measurement.isEmpty()) {
|
||||
if (peakMap == null) {
|
||||
@ -490,13 +512,14 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
if (isFilamentOn()) {
|
||||
mspListener.acceptScan(measurement);
|
||||
|
||||
for (PointLoader loader : this.loaders) {
|
||||
forEachTypedConnection(Roles.STORAGE_ROLE, StorageConnection.class, (StorageConnection connection) -> {
|
||||
PointLoader pl = loaderMap.computeIfAbsent(connection, con -> makeLoader(con));
|
||||
try {
|
||||
loader.push(point);
|
||||
pl.push(point);
|
||||
} catch (StorageException ex) {
|
||||
getLogger().error("Push to repo failed", ex);
|
||||
getLogger().error("Push to loader failed", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
measurement.clear();
|
||||
@ -505,7 +528,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
||||
|
||||
if (numScans == 0) {
|
||||
try {
|
||||
send("ScanResume", 2);
|
||||
send("ScanResume", 10);
|
||||
//FIXME обработать ошибку связи
|
||||
} catch (PortException ex) {
|
||||
error(null, ex);
|
||||
|
@ -17,9 +17,11 @@ package inr.numass.control.msp.fx;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import hep.dataforge.context.GlobalContext;
|
||||
import hep.dataforge.io.MetaFileReader;
|
||||
import hep.dataforge.io.XMLMetaReader;
|
||||
import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.storage.commons.StorageManager;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
@ -37,26 +39,31 @@ public class MspApp extends Application {
|
||||
MspViewController controller;
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
Locale.setDefault(Locale.US);// чтобы отделение десятичных знаков было точкой
|
||||
ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
|
||||
rootLogger.setLevel(Level.INFO);
|
||||
new StorageManager().startGlobal();
|
||||
|
||||
String configFileName = getParameters().getNamed().get("config");
|
||||
if (configFileName == null) {
|
||||
configFileName = "msp-config.xml";
|
||||
}
|
||||
File configFile = new File(configFileName);
|
||||
Meta config;
|
||||
if (configFile.exists()) {
|
||||
config = MetaFileReader.read(configFile).build();
|
||||
} else {
|
||||
// throw new RuntimeException("Configuration file not found");
|
||||
config = new XMLMetaReader().read(MspApp.class.getClassLoader().getResourceAsStream("config/msp-config.xml"), -1, null);
|
||||
}
|
||||
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/MspView.fxml"));
|
||||
|
||||
Parent parent = loader.load();
|
||||
controller = loader.getController();
|
||||
|
||||
try {
|
||||
String configPath = getParameters().getNamed().get("config");
|
||||
if (configPath != null) {
|
||||
File configFile = new File(configPath);
|
||||
controller.setDeviceConfig(GlobalContext.instance(), configFile);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LoggerFactory.getLogger(getClass()).error("Failed to load predefined configuration", ex);
|
||||
}
|
||||
controller.setDeviceConfig(GlobalContext.instance(), config);
|
||||
|
||||
Scene scene = new Scene(parent, 600, 400);
|
||||
|
||||
@ -72,9 +79,9 @@ public class MspApp extends Application {
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
super.stop(); //To change body of generated methods, choose Tools | Templates.
|
||||
controller.disconnect();
|
||||
System.exit(0);
|
||||
super.stop();
|
||||
controller.shutdown();
|
||||
// System.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,8 @@ import hep.dataforge.control.connections.StorageConnection;
|
||||
import hep.dataforge.points.MapPoint;
|
||||
import hep.dataforge.exceptions.ControlException;
|
||||
import hep.dataforge.exceptions.PortException;
|
||||
import hep.dataforge.exceptions.StorageException;
|
||||
import hep.dataforge.fx.ConsoleWindow;
|
||||
import hep.dataforge.io.MetaFileReader;
|
||||
import hep.dataforge.meta.ConfigChangeListener;
|
||||
import hep.dataforge.meta.Configuration;
|
||||
@ -29,9 +31,10 @@ import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.meta.MetaBuilder;
|
||||
import hep.dataforge.plots.data.DynamicPlottable;
|
||||
import hep.dataforge.plots.data.DynamicPlottableSet;
|
||||
import hep.dataforge.plots.fx.PlotContainer;
|
||||
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
||||
import hep.dataforge.storage.api.Storage;
|
||||
import hep.dataforge.storage.commons.StorageManager;
|
||||
import hep.dataforge.storage.filestorage.FileStorage;
|
||||
import hep.dataforge.values.Value;
|
||||
import inr.numass.control.msp.MspDevice;
|
||||
import inr.numass.control.msp.MspListener;
|
||||
@ -44,11 +47,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
@ -56,8 +60,12 @@ import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.util.StringConverter;
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import inr.numass.client.NumassClient;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
/**
|
||||
* FXML Controller class
|
||||
@ -74,26 +82,13 @@ public class MspViewController implements Initializable, MspListener {
|
||||
|
||||
private Configuration viewConfig;
|
||||
|
||||
private JFreeChartFrame plotFrame;
|
||||
private JFreeChartFrame plot;
|
||||
|
||||
private final DynamicPlottableSet plottables = new DynamicPlottableSet();
|
||||
|
||||
private final String mspName = "msp";
|
||||
|
||||
@FXML
|
||||
private Slider autoRangeSlider;
|
||||
@FXML
|
||||
private ToggleButton fillamentButton;
|
||||
@FXML
|
||||
private Circle fillamentIndicator;
|
||||
@FXML
|
||||
private TextArea logArea;
|
||||
@FXML
|
||||
private ToggleButton plotButton;
|
||||
@FXML
|
||||
private AnchorPane plotPane;
|
||||
@FXML
|
||||
private Button loadConfigButton;
|
||||
|
||||
private final ConfigChangeListener viewConfigObserver = new ConfigChangeListener() {
|
||||
|
||||
@ -109,7 +104,57 @@ public class MspViewController implements Initializable, MspListener {
|
||||
|
||||
};
|
||||
|
||||
public MspViewController() {
|
||||
private StorageConnection connection;
|
||||
|
||||
@FXML
|
||||
private Slider autoRangeSlider;
|
||||
@FXML
|
||||
private ToggleSwitch fillamentButton;
|
||||
@FXML
|
||||
private Circle fillamentIndicator;
|
||||
@FXML
|
||||
private ToggleButton plotButton;
|
||||
@FXML
|
||||
private AnchorPane plotPane;
|
||||
@FXML
|
||||
private ToggleButton consoleButton;
|
||||
@FXML
|
||||
private ComboBox<Integer> fillamentSelector;
|
||||
@FXML
|
||||
private ToggleButton storeButton;
|
||||
|
||||
/**
|
||||
* Initializes the controller class.
|
||||
*
|
||||
* @param url
|
||||
* @param rb
|
||||
*/
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
ConsoleWindow cw = new ConsoleWindow(consoleButton);
|
||||
this.logArea = cw.getTextArea();
|
||||
fillamentSelector.setItems(FXCollections.observableArrayList(1, 2));
|
||||
fillamentSelector.setConverter(new StringConverter<Integer>() {
|
||||
@Override
|
||||
public String toString(Integer object) {
|
||||
return "Fillament " + object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer fromString(String string) {
|
||||
return Integer.parseInt(string.substring(9));
|
||||
}
|
||||
});
|
||||
|
||||
fillamentSelector.getSelectionModel().select(0);
|
||||
fillamentButton.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
|
||||
try {
|
||||
fillamentSelector.setDisable(newValue);
|
||||
getDevice().setFileamentOn(newValue);
|
||||
} catch (PortException ex) {
|
||||
device.getLogger().error("Failed to toggle fillaments");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Configuration getViewConfig() {
|
||||
@ -159,9 +204,7 @@ public class MspViewController implements Initializable, MspListener {
|
||||
device.setName(mspName);
|
||||
device.setContext(context);
|
||||
device.setMeta(mspConfig);
|
||||
if (mspConfig.hasNode("storage")) {
|
||||
device.connect(new StorageConnection(StorageManager.buildFrom(context).buildStorage(mspConfig.getNode("storage"))), Roles.STORAGE_ROLE);
|
||||
}
|
||||
|
||||
try {
|
||||
getDevice().setListener(this);
|
||||
getDevice().init();
|
||||
@ -201,19 +244,22 @@ public class MspViewController implements Initializable, MspListener {
|
||||
.setValue("axisUnits", "mbar")
|
||||
)
|
||||
.setValue("xAxis.type", "time");
|
||||
this.plotFrame = new JFreeChartFrame(mspName, plotConfig).display(plotPane);
|
||||
|
||||
this.plot = new JFreeChartFrame(mspName, plotConfig);
|
||||
PlotContainer container = PlotContainer.anchorTo(plotPane);
|
||||
container.setPlot(plot);
|
||||
updatePlot();
|
||||
// this.plot = DynamicPlot.attachToFX(plotPane, new AnnotationBuilder("plot-config").putValue("logY", true).build());
|
||||
// plot.setAutoRange(30 * 60);
|
||||
}
|
||||
|
||||
public void updatePlot() {
|
||||
if (plotFrame == null) {
|
||||
if (plot == null) {
|
||||
initPlot();
|
||||
}
|
||||
Meta config = getViewConfig();
|
||||
if (config.hasNode("plotFrame")) {
|
||||
this.plotFrame.configure(config.getNode("plotFrame"));
|
||||
this.plot.configure(config.getNode("plotFrame"));
|
||||
}
|
||||
if (config.hasNode("peakJump.line")) {
|
||||
for (Meta an : config.getNodes("peakJump.line")) {
|
||||
@ -223,7 +269,7 @@ public class MspViewController implements Initializable, MspListener {
|
||||
DynamicPlottable newPlottable = new DynamicPlottable(mass, mass);
|
||||
newPlottable.configure(an);
|
||||
this.plottables.addPlottable(newPlottable);
|
||||
plotFrame.add(newPlottable);
|
||||
plot.add(newPlottable);
|
||||
} else {
|
||||
plottables.getPlottable(mass).configure(an);
|
||||
}
|
||||
@ -270,40 +316,11 @@ public class MspViewController implements Initializable, MspListener {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the controller class.
|
||||
*
|
||||
* @param url
|
||||
* @param rb
|
||||
*/
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onAutoRangeChange(DragEvent event) {
|
||||
plottables.setMaxAge((int) (this.autoRangeSlider.getValue() * 60 * 1000));
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onFillamentToggle(ActionEvent event) throws PortException {
|
||||
getDevice().setFileamentOn(fillamentButton.isSelected());
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onLoadConfig(ActionEvent event) {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Open Resource File");
|
||||
fileChooser.setInitialFileName(DEFAULT_CONFIG_LOCATION);
|
||||
fileChooser.setInitialDirectory(GlobalContext.instance().io().getRootDirectory());
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("xml", "*.xml", "*.XML"));
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("all", "*.*"));
|
||||
File cfgFile = fileChooser.showOpenDialog(loadConfigButton.getScene().getWindow());
|
||||
if (cfgFile != null) {
|
||||
setDeviceConfig(GlobalContext.instance(), cfgFile);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onPlotToggle(ActionEvent event) throws ControlException {
|
||||
if (plotButton.isSelected()) {
|
||||
@ -326,7 +343,7 @@ public class MspViewController implements Initializable, MspListener {
|
||||
|
||||
}
|
||||
|
||||
public void disconnect() throws IOException, PortException, ControlException {
|
||||
public void shutdown() throws IOException, PortException, ControlException {
|
||||
getDevice().shutdown();
|
||||
}
|
||||
|
||||
@ -349,4 +366,52 @@ public class MspViewController implements Initializable, MspListener {
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onStoreButtonClick(ActionEvent event) {
|
||||
if (storeButton.isSelected()) {
|
||||
|
||||
if (!device.meta().hasNode("storage")) {
|
||||
device.getLogger().info("Storage not defined. Starting storage selection dialog");
|
||||
DirectoryChooser chooser = new DirectoryChooser();
|
||||
File storageDir = chooser.showDialog(this.plotPane.getScene().getWindow());
|
||||
if (storageDir == null) {
|
||||
storeButton.setSelected(false);
|
||||
throw new RuntimeException("User canceled directory selection");
|
||||
}
|
||||
device.getConfig().putNode(new MetaBuilder("storage")
|
||||
.putValue("path", storageDir.getAbsolutePath()));
|
||||
}
|
||||
Meta storageConfig = device.meta().getNode("storage");
|
||||
Storage localStorage = StorageManager.buildFrom(device.getContext())
|
||||
.buildStorage(storageConfig);
|
||||
|
||||
String runName = device.meta().getString("numass.run", "");
|
||||
Meta meta = device.meta();
|
||||
if (meta.hasNode("numass")) {
|
||||
try {
|
||||
device.getLogger().info("Obtaining run information from cetral server...");
|
||||
NumassClient client = new NumassClient(meta.getString("numass.ip", "192.168.111.1"),
|
||||
meta.getInt("numass.port", 8335));
|
||||
runName = client.getCurrentRun().getString("path", "");
|
||||
device.getLogger().info("Run name is '{}'", runName);
|
||||
} catch (Exception ex) {
|
||||
device.getLogger().warn("Failed to download current run information", ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!runName.isEmpty()) {
|
||||
try {
|
||||
localStorage = localStorage.buildShelf(runName, null);
|
||||
} catch (StorageException ex) {
|
||||
device.getLogger().error("Failed to create storage shelf. Using root storage instead");
|
||||
}
|
||||
}
|
||||
|
||||
connection = new StorageConnection(localStorage);
|
||||
device.connect(connection, Roles.STORAGE_ROLE);
|
||||
} else if (connection != null) {
|
||||
device.disconnect(connection);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,58 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2015 Alexander Nozik.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<?import javafx.scene.effect.*?>
|
||||
<?import javafx.scene.paint.*?>
|
||||
<?import javafx.scene.shape.*?>
|
||||
<?import javafx.scene.chart.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import java.util.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<!--
|
||||
Copyright 2015 Alexander Nozik.
|
||||
|
||||
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="400.0" minWidth="600.0" prefHeight="480.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.control.msp.fx.MspViewController">
|
||||
<children>
|
||||
<SplitPane dividerPositions="0.8" minHeight="400.0" minWidth="600.0" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<items>
|
||||
<AnchorPane minHeight="300.0" minWidth="300.0" prefHeight="100.0" prefWidth="160.0">
|
||||
<children>
|
||||
<ToolBar layoutX="130.0" prefHeight="50.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<items>
|
||||
<ToggleButton fx:id="fillamentButton" mnemonicParsing="false" onAction="#onFillamentToggle" text="Fillament" />
|
||||
<Circle fx:id="fillamentIndicator" fill="GRAY" radius="10.0" stroke="BLACK" strokeType="INSIDE" />
|
||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||
<ToggleButton fx:id="plotButton" mnemonicParsing="false" onAction="#onPlotToggle" text="Aquire" />
|
||||
<Button fx:id="loadConfigButton" mnemonicParsing="false" onAction="#onLoadConfig" text="Load config" />
|
||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||
<Label text="Autorange (min):" />
|
||||
<Slider fx:id="autoRangeSlider" max="210.0" min="10.0" onDragDone="#onAutoRangeChange" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="30.0" />
|
||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||
</items>
|
||||
</ToolBar>
|
||||
<AnchorPane fx:id="plotPane" layoutX="144.0" layoutY="82.0" minHeight="400.0" minWidth="600.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane maxHeight="200.0" minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
|
||||
<children>
|
||||
<TextArea fx:id="logArea" editable="false" maxHeight="200.0" minHeight="0.0" prefHeight="200.0" prefWidth="200.0" wrapText="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</items>
|
||||
</SplitPane>
|
||||
</children>
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.control.Slider?>
|
||||
<?import javafx.scene.control.ToggleButton?>
|
||||
<?import javafx.scene.control.ToolBar?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import org.controlsfx.control.ToggleSwitch?>
|
||||
|
||||
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="400.0" minWidth="600.0" prefHeight="480.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.control.msp.fx.MspViewController">
|
||||
<children>
|
||||
<ToolBar prefHeight="50.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<items>
|
||||
<ComboBox fx:id="fillamentSelector" promptText="Fillament 1" visibleRowCount="2" />
|
||||
<ToggleSwitch fx:id="fillamentButton" prefHeight="40.0" prefWidth="35.0">
|
||||
<padding>
|
||||
<Insets top="11.0" />
|
||||
</padding>
|
||||
</ToggleSwitch>
|
||||
<Circle fx:id="fillamentIndicator" fill="GRAY" radius="10.0" stroke="BLACK" strokeType="INSIDE" />
|
||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||
<ToggleButton fx:id="plotButton" mnemonicParsing="false" onAction="#onPlotToggle" text="Measure" />
|
||||
<ToggleButton fx:id="storeButton" mnemonicParsing="false" onAction="#onStoreButtonClick" text="Store" />
|
||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||
<Label text="Autorange (min):" />
|
||||
<Slider fx:id="autoRangeSlider" max="210.0" min="10.0" onDragDone="#onAutoRangeChange" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="30.0" />
|
||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<ToggleButton fx:id="consoleButton" mnemonicParsing="false" text="Console" />
|
||||
</items>
|
||||
</ToolBar>
|
||||
<AnchorPane fx:id="plotPane" minHeight="400.0" minWidth="600.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
@ -81,7 +81,7 @@ public class ReadVac extends Application {
|
||||
|
||||
controller.setLoaderFactory((VacCollectorDevice device, Storage localStorage) -> {
|
||||
try {
|
||||
String runName = device.meta().getString("storage.run", "");
|
||||
String runName = device.meta().getString("numass.run", "");
|
||||
if (config.hasNode("numass")) {
|
||||
try {
|
||||
logger.info("Obtaining run information from cetral server...");
|
||||
|
@ -5,8 +5,7 @@
|
||||
*/
|
||||
package inr.numass.readvac.fx;
|
||||
|
||||
import de.jensd.shichimifx.utils.ConsoleDude;
|
||||
import hep.dataforge.control.connections.Connection;
|
||||
import hep.dataforge.control.connections.LoaderConnection;
|
||||
import hep.dataforge.control.connections.Roles;
|
||||
import hep.dataforge.control.devices.Device;
|
||||
import hep.dataforge.control.devices.DeviceListener;
|
||||
@ -16,7 +15,7 @@ import hep.dataforge.control.measurements.Sensor;
|
||||
import hep.dataforge.points.DataPoint;
|
||||
import hep.dataforge.exceptions.ControlException;
|
||||
import hep.dataforge.exceptions.MeasurementException;
|
||||
import hep.dataforge.exceptions.StorageException;
|
||||
import hep.dataforge.fx.ConsoleWindow;
|
||||
import hep.dataforge.meta.Meta;
|
||||
import hep.dataforge.meta.MetaBuilder;
|
||||
import hep.dataforge.plots.PlotFrame;
|
||||
@ -25,7 +24,6 @@ import hep.dataforge.plots.data.DynamicPlottableSet;
|
||||
import hep.dataforge.plots.fx.PlotContainer;
|
||||
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
||||
import hep.dataforge.points.FormatBuilder;
|
||||
import hep.dataforge.points.PointListener;
|
||||
import hep.dataforge.storage.api.PointLoader;
|
||||
import hep.dataforge.storage.api.Storage;
|
||||
import hep.dataforge.storage.commons.LoaderFactory;
|
||||
@ -49,16 +47,12 @@ import javafx.collections.FXCollections;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
import javafx.util.Duration;
|
||||
import org.controlsfx.control.Notifications;
|
||||
import org.slf4j.Logger;
|
||||
@ -86,9 +80,8 @@ public class VacCollectorController implements Initializable, DeviceListener, Me
|
||||
private DynamicPlottableSet plottables;
|
||||
private BiFunction<VacCollectorDevice, Storage, PointLoader> loaderFactory;
|
||||
|
||||
private TextArea consolePane;
|
||||
private Stage consoleWindow;
|
||||
|
||||
ConsoleWindow consoleWindow;
|
||||
|
||||
@FXML
|
||||
private AnchorPane plotHolder;
|
||||
@FXML
|
||||
@ -122,20 +115,8 @@ public class VacCollectorController implements Initializable, DeviceListener, Me
|
||||
}
|
||||
});
|
||||
|
||||
consolePane = new TextArea();
|
||||
consolePane.setEditable(false);
|
||||
consolePane.setWrapText(true);
|
||||
// consolePane.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
|
||||
// if (newValue.length() > 10000) {
|
||||
// consolePane.clear();
|
||||
// }
|
||||
// });
|
||||
consoleWindow = new Stage();
|
||||
consoleWindow.setTitle("Vacuum measurement console");
|
||||
consoleWindow.setScene(new Scene(consolePane, 800, 200));
|
||||
consoleWindow.setOnHidden((WindowEvent event) -> {
|
||||
logButton.setSelected(false);
|
||||
});
|
||||
consoleWindow = new ConsoleWindow(logButton);
|
||||
consoleWindow.hookStd();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -297,17 +278,6 @@ public class VacCollectorController implements Initializable, DeviceListener, Me
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onLogToggle(ActionEvent event) {
|
||||
if (logButton.isSelected() && logButton.isSelected() != consoleWindow.isShowing()) {
|
||||
consoleWindow.show();
|
||||
ConsoleDude.hookStdStreams(consolePane);
|
||||
} else {
|
||||
consoleWindow.hide();
|
||||
ConsoleDude.restoreStdStreams();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the logger
|
||||
*/
|
||||
@ -324,39 +294,4 @@ public class VacCollectorController implements Initializable, DeviceListener, Me
|
||||
public void setLogger(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
private class LoaderConnection implements PointListener, Connection<Device> {
|
||||
|
||||
private final PointLoader loader;
|
||||
|
||||
public LoaderConnection(PointLoader loader) {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(DataPoint point) {
|
||||
try {
|
||||
loader.push(point);
|
||||
} catch (StorageException ex) {
|
||||
getLogger().error("Error while pushing data", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return loader.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Device object) throws Exception {
|
||||
loader.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
loader.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.net.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
@ -19,7 +13,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<AnchorPane id="root" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.readvac.fx.VacCollectorController">
|
||||
<AnchorPane id="root" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.readvac.fx.VacCollectorController">
|
||||
<stylesheets>
|
||||
<URL value="@/styles/vacstyles.css" />
|
||||
</stylesheets>
|
||||
@ -38,7 +32,7 @@
|
||||
<Separator orientation="VERTICAL" />
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<Separator orientation="VERTICAL" />
|
||||
<ToggleButton fx:id="logButton" mnemonicParsing="false" onAction="#onLogToggle" text="Console" />
|
||||
<ToggleButton fx:id="logButton" mnemonicParsing="false" text="Console" />
|
||||
</items>
|
||||
</ToolBar>
|
||||
<AnchorPane fx:id="plotHolder" VBox.vgrow="ALWAYS" />
|
||||
|
Loading…
Reference in New Issue
Block a user