numass cryotemp update
This commit is contained in:
parent
50947c9219
commit
f9f605bde0
@ -21,4 +21,12 @@ task debug(dependsOn: classes, type: JavaExec) {
|
|||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
description "Start application in debug mode with default virtual port"
|
description "Start application in debug mode with default virtual port"
|
||||||
group "debug"
|
group "debug"
|
||||||
|
}
|
||||||
|
|
||||||
|
task testRun(dependsOn: classes, type: JavaExec) {
|
||||||
|
main mainClass
|
||||||
|
args(["--cfgFile=D:/temp/test/numass-devices.xml", "--device=thermo-1"])
|
||||||
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
description "Start application using real device"
|
||||||
|
group "debug"
|
||||||
}
|
}
|
@ -16,10 +16,16 @@
|
|||||||
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.io.MetaFileReader;
|
import hep.dataforge.io.MetaFileReader;
|
||||||
|
import hep.dataforge.meta.Meta;
|
||||||
|
import hep.dataforge.meta.MetaUtils;
|
||||||
|
import hep.dataforge.storage.commons.StorageFactory;
|
||||||
import hep.dataforge.storage.commons.StorageManager;
|
import hep.dataforge.storage.commons.StorageManager;
|
||||||
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;
|
||||||
@ -28,6 +34,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@ -35,54 +42,10 @@ import java.util.Locale;
|
|||||||
* @author darksnake
|
* @author darksnake
|
||||||
*/
|
*/
|
||||||
public class PKT8App extends Application {
|
public class PKT8App extends Application {
|
||||||
|
public static final String DEFAULT_CONFIG_LOCATION = "numass-devices.xml";
|
||||||
PKT8MainViewController controller;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(Stage primaryStage) throws IOException, ControlException, ParseException {
|
|
||||||
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();
|
|
||||||
|
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8MainView.fxml"));
|
|
||||||
|
|
||||||
Parent parent = loader.load();
|
|
||||||
controller = loader.getController();
|
|
||||||
|
|
||||||
// Meta deviceMeta = XMLMetaConverter.fromStream(getClass().getResourceAsStream("/defaultConfig.xml"));
|
|
||||||
|
|
||||||
// controller.setupDevice(deviceMeta);
|
|
||||||
|
|
||||||
Scene scene = new Scene(parent, 600, 400);
|
|
||||||
|
|
||||||
|
|
||||||
primaryStage.setTitle("PKT8 cryogenic temperature viewer");
|
PKT8Device device;
|
||||||
primaryStage.setScene(scene);
|
|
||||||
primaryStage.setMinHeight(400);
|
|
||||||
primaryStage.setMinWidth(600);
|
|
||||||
// primaryStage.setResizable(false);
|
|
||||||
|
|
||||||
primaryStage.show();
|
|
||||||
|
|
||||||
if (getParameters().getNamed().containsKey("cfgFile")) {
|
|
||||||
controller.setConfig(MetaFileReader.read(new File(getParameters().getNamed().get("cfgFile"))));
|
|
||||||
} else if (Boolean.parseBoolean(getParameters().getNamed().getOrDefault("debug", "false"))) {
|
|
||||||
controller.loadTestConfig();
|
|
||||||
} else {
|
|
||||||
controller.startConfigDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop() throws Exception {
|
|
||||||
super.stop();
|
|
||||||
if (controller != null) {
|
|
||||||
controller.close();
|
|
||||||
controller = null;
|
|
||||||
}
|
|
||||||
// System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
@ -91,4 +54,109 @@ public class PKT8App extends Application {
|
|||||||
launch(args);
|
launch(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public Meta startConfigDialog(Scene scene) throws IOException, ParseException, ControlException {
|
||||||
|
// FileChooser fileChooser = new FileChooser();
|
||||||
|
// fileChooser.setTitle("Open configuration 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("json", "*.json", "*.JSON"));
|
||||||
|
//// fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("all", "*.*"));
|
||||||
|
// File cfgFile = fileChooser.showOpenDialog(scene.getWindow());
|
||||||
|
//
|
||||||
|
// if (cfgFile != null) {
|
||||||
|
// return MetaFileReader.read(cfgFile);
|
||||||
|
// } else {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) throws IOException, ControlException, ParseException {
|
||||||
|
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 deviceName = getParameters().getNamed().getOrDefault("device", "PKT-8");
|
||||||
|
|
||||||
|
Meta config;
|
||||||
|
|
||||||
|
if (Boolean.parseBoolean(getParameters().getNamed().getOrDefault("debug", "false"))) {
|
||||||
|
config = loadTestConfig();
|
||||||
|
} else {
|
||||||
|
config = MetaFileReader.read(new File(getParameters().getNamed().getOrDefault("cfgFile", DEFAULT_CONFIG_LOCATION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
device = setupDevice(deviceName, config);
|
||||||
|
|
||||||
|
// setting up storage connections
|
||||||
|
if (config.hasNode("storage")) {
|
||||||
|
config.getNodes("storage").forEach(node -> {
|
||||||
|
device.connect(new StorageConnection(StorageFactory.buildStorage(device.getContext(), node)), Roles.STORAGE_ROLE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Indicator.fxml"));
|
||||||
|
PKT8Controller controller = new PKT8Controller(device);
|
||||||
|
loader.setController(controller);
|
||||||
|
|
||||||
|
Parent parent = loader.load();
|
||||||
|
|
||||||
|
|
||||||
|
Scene scene = new Scene(parent, 400, 400);
|
||||||
|
primaryStage.setTitle("Numass temperature view");
|
||||||
|
primaryStage.setScene(scene);
|
||||||
|
primaryStage.setMinHeight(400);
|
||||||
|
primaryStage.setMinWidth(400);
|
||||||
|
// primaryStage.setResizable(false);
|
||||||
|
|
||||||
|
primaryStage.show();
|
||||||
|
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
try {
|
||||||
|
device.init();
|
||||||
|
// controller.start();
|
||||||
|
} catch (ControlException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Meta loadTestConfig() throws ControlException {
|
||||||
|
try {
|
||||||
|
return MetaFileReader
|
||||||
|
.read(new File(getClass().getResource("/config/defaultConfig.xml").toURI()));
|
||||||
|
} catch (URISyntaxException | IOException | ParseException ex) {
|
||||||
|
throw new Error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PKT8Device setupDevice(String deviceName, Meta config) throws ControlException {
|
||||||
|
Meta deviceMeta;
|
||||||
|
|
||||||
|
if (config.hasNode("device")) {
|
||||||
|
deviceMeta = MetaUtils.findNodeByValue(config, "device", "name", deviceName);
|
||||||
|
} else {
|
||||||
|
deviceMeta = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
PKT8Device device = new PKT8Device(deviceMeta.getString("port", "virtual"));
|
||||||
|
|
||||||
|
device.configure(deviceMeta);
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() throws Exception {
|
||||||
|
super.stop();
|
||||||
|
if (device != null) {
|
||||||
|
device.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,125 @@
|
|||||||
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
|
import hep.dataforge.control.devices.Device;
|
||||||
|
import hep.dataforge.control.devices.DeviceListener;
|
||||||
|
import hep.dataforge.control.measurements.Measurement;
|
||||||
|
import hep.dataforge.control.measurements.MeasurementListener;
|
||||||
|
import hep.dataforge.exceptions.ControlException;
|
||||||
|
import hep.dataforge.exceptions.MeasurementException;
|
||||||
|
import hep.dataforge.fx.ConsoleFragment;
|
||||||
|
import hep.dataforge.values.Value;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.TableColumn;
|
||||||
|
import javafx.scene.control.TableView;
|
||||||
|
import javafx.scene.control.ToggleButton;
|
||||||
|
import javafx.scene.control.cell.PropertyValueFactory;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by darksnake on 07-Oct-16.
|
||||||
|
*/
|
||||||
|
public class PKT8Controller implements Initializable, DeviceListener, MeasurementListener<PKT8Result> {
|
||||||
|
|
||||||
|
private final PKT8Device device;
|
||||||
|
private ConsoleFragment consoleFragment;
|
||||||
|
private PKT8PlotFragment plotFragment;
|
||||||
|
@FXML
|
||||||
|
private ToggleButton startStopButton;
|
||||||
|
@FXML
|
||||||
|
private ToggleButton consoleButton;
|
||||||
|
@FXML
|
||||||
|
private ToggleButton plotButton;
|
||||||
|
@FXML
|
||||||
|
private Label lastUpdateLabel;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TableView<PKT8Result> table;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TableColumn<TableView<PKT8Result>, String> sensorColumn;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TableColumn<TableView<PKT8Result>, Double> resColumn;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TableColumn<TableView<PKT8Result>, String> tempColumn;
|
||||||
|
|
||||||
|
|
||||||
|
public PKT8Controller(PKT8Device device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
this.consoleFragment = new ConsoleFragment();
|
||||||
|
consoleFragment.bindTo(consoleButton);
|
||||||
|
plotFragment = new PKT8PlotFragment(device);
|
||||||
|
plotFragment.bindTo(plotButton);
|
||||||
|
|
||||||
|
sensorColumn.setCellValueFactory(new PropertyValueFactory<>("channel"));
|
||||||
|
resColumn.setCellValueFactory(new PropertyValueFactory<>("rawString"));
|
||||||
|
tempColumn.setCellValueFactory(new PropertyValueFactory<>("temperatureString"));
|
||||||
|
startStopButton.selectedProperty().setValue(device.isMeasuring());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMeasurementResult(Measurement<PKT8Result> measurement, PKT8Result result, Instant time) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
lastUpdateLabel.setText(time.toString());
|
||||||
|
table.getItems().removeIf(it -> it.channel.equals(result.channel));
|
||||||
|
table.getItems().add(result);
|
||||||
|
table.getItems().sort((o1, o2) -> o1.channel.compareTo(o2.channel));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMeasurementFailed(Measurement measurement, Throwable exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyDeviceStateChanged(Device device, String name, Value state) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evaluateDeviceException(Device device, String message, Throwable exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void start() throws MeasurementException {
|
||||||
|
device.startMeasurement().addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() throws MeasurementException {
|
||||||
|
if (device.isMeasuring()) {
|
||||||
|
device.getMeasurement().removeListener(this);
|
||||||
|
device.stopMeasurement(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private void onStartStopClick(ActionEvent event) {
|
||||||
|
if (device != null) {
|
||||||
|
try {
|
||||||
|
if (startStopButton.isSelected()) {
|
||||||
|
start();
|
||||||
|
} else {
|
||||||
|
//in case device started
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
} catch (ControlException ex) {
|
||||||
|
evaluateDeviceException(device, "Failed to start or stop device", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ import hep.dataforge.control.connections.PointListenerConnection;
|
|||||||
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.PortSensor;
|
import hep.dataforge.control.devices.PortSensor;
|
||||||
|
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;
|
||||||
@ -30,8 +31,8 @@ import hep.dataforge.exceptions.PortException;
|
|||||||
import hep.dataforge.exceptions.StorageException;
|
import hep.dataforge.exceptions.StorageException;
|
||||||
import hep.dataforge.meta.Meta;
|
import hep.dataforge.meta.Meta;
|
||||||
import hep.dataforge.storage.api.PointLoader;
|
import hep.dataforge.storage.api.PointLoader;
|
||||||
|
import hep.dataforge.storage.api.Storage;
|
||||||
import hep.dataforge.storage.commons.LoaderFactory;
|
import hep.dataforge.storage.commons.LoaderFactory;
|
||||||
import hep.dataforge.storage.commons.StorageFactory;
|
|
||||||
import hep.dataforge.tables.DataPoint;
|
import hep.dataforge.tables.DataPoint;
|
||||||
import hep.dataforge.tables.PointListener;
|
import hep.dataforge.tables.PointListener;
|
||||||
import hep.dataforge.tables.TableFormatBuilder;
|
import hep.dataforge.tables.TableFormatBuilder;
|
||||||
@ -39,12 +40,15 @@ import hep.dataforge.tables.TableFormatBuilder;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A device controller for Dubna PKT 8 cryogenic thermometry device
|
* A device controller for Dubna PKT 8 cryogenic thermometry device
|
||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
|
@RoleDef(name = Roles.STORAGE_ROLE)
|
||||||
|
@RoleDef(name = Roles.POINT_LISTENER_ROLE)
|
||||||
public class PKT8Device extends PortSensor<PKT8Result> {
|
public class PKT8Device extends PortSensor<PKT8Result> {
|
||||||
|
|
||||||
public static final String PGA = "pga";
|
public static final String PGA = "pga";
|
||||||
@ -55,7 +59,6 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
* The key is the letter (a,b,c,d...) as in measurements
|
* The key is the letter (a,b,c,d...) as in measurements
|
||||||
*/
|
*/
|
||||||
private final Map<String, PKT8Channel> channels = new HashMap<>();
|
private final Map<String, PKT8Channel> channels = new HashMap<>();
|
||||||
// private PointLoader pointLoader;
|
|
||||||
private RegularPointCollector collector;
|
private RegularPointCollector collector;
|
||||||
|
|
||||||
public PKT8Device(String portName) {
|
public PKT8Device(String portName) {
|
||||||
@ -95,7 +98,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
setSPS(meta().getInt("sps", 0));
|
setSPS(meta().getInt("sps", 0));
|
||||||
setBUF(meta().getInt("abuf", 100));
|
setBUF(meta().getInt("abuf", 100));
|
||||||
|
|
||||||
setupStorage();
|
setupLoaders();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +243,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
return getState(ABUF).stringValue();
|
return getState(ABUF).stringValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupStorage() {
|
private void setupLoaders() {
|
||||||
|
|
||||||
// Building data format
|
// Building data format
|
||||||
TableFormatBuilder tableFormatBuilder = new TableFormatBuilder()
|
TableFormatBuilder tableFormatBuilder = new TableFormatBuilder()
|
||||||
@ -252,24 +255,21 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
names.add(channel.getName());
|
names.add(channel.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// setting up storage connections
|
|
||||||
if (meta().hasNode("storage")) {
|
|
||||||
meta().getNodes("storage").forEach(node -> {
|
|
||||||
connect(new StorageConnection(StorageFactory.buildStorage(getContext(), node)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// setting up loader for each of storages
|
// setting up loader for each of storages
|
||||||
forEachTypedConnection(Roles.STORAGE_ROLE, StorageConnection.class, connection -> {
|
List<Storage> storages = connections().filter(it -> it.getValue()
|
||||||
|
.contains(Roles.STORAGE_ROLE) && it.getKey() instanceof StorageConnection)
|
||||||
|
.map(it -> ((StorageConnection) it.getKey()).getStorage()).collect(Collectors.toList());
|
||||||
|
|
||||||
|
storages.forEach(storage -> {
|
||||||
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
|
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
|
||||||
|
|
||||||
PointLoader pointLoader = null;
|
PointLoader pointLoader = null;
|
||||||
try {
|
try {
|
||||||
pointLoader = LoaderFactory.buildPointLoder(connection.getStorage(),
|
pointLoader = LoaderFactory.buildPointLoder(storage,
|
||||||
"cryotemp_" + suffix, "", "timestamp", tableFormatBuilder.build());
|
"cryotemp_" + suffix, "", "timestamp", tableFormatBuilder.build());
|
||||||
this.connect(new LoaderConnection(pointLoader), Roles.POINT_LISTENER_ROLE);
|
this.connect(new LoaderConnection(pointLoader), Roles.POINT_LISTENER_ROLE);
|
||||||
} catch (StorageException e) {
|
} catch (StorageException e) {
|
||||||
getLogger().error("Failed to build loader from storage {}", connection.getStorage().getName());
|
getLogger().error("Failed to build loader from storage {}", storage.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -284,7 +284,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
}, duration, names);
|
}, duration, names);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectPointListener(PointListenerConnection listener){
|
public void connectPointListener(PointListenerConnection listener) {
|
||||||
this.connect(listener, Roles.POINT_LISTENER_ROLE);
|
this.connect(listener, Roles.POINT_LISTENER_ROLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,6 +334,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
getLogger().info("Starting measurement");
|
||||||
handler.holdBy(this);
|
handler.holdBy(this);
|
||||||
handler.send("s");
|
handler.send("s");
|
||||||
afterStart();
|
afterStart();
|
||||||
@ -350,6 +351,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
getLogger().info("Stopping measurement");
|
||||||
String response = getHandler().sendAndWait("p", 400).trim();
|
String response = getHandler().sendAndWait("p", 400).trim();
|
||||||
// Должно быть именно с большой буквы!!!
|
// Должно быть именно с большой буквы!!!
|
||||||
return "Stopped".equals(response) || "stopped".equals(response);
|
return "Stopped".equals(response) || "stopped".equals(response);
|
||||||
@ -372,7 +374,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
if (isStarted()) {
|
if (isStarted()) {
|
||||||
if (trimmed.equals("Stopped") || trimmed.equals("stopped")) {
|
if (trimmed.equals("Stopped") || trimmed.equals("stopped")) {
|
||||||
afterPause();
|
afterPause();
|
||||||
getLogger().info("Measurement stopped");
|
// getLogger().info("Measurement stopped");
|
||||||
} else {
|
} else {
|
||||||
String designation = trimmed.substring(0, 1);
|
String designation = trimmed.substring(0, 1);
|
||||||
double rawValue = Double.parseDouble(trimmed.substring(1)) / 100;
|
double rawValue = Double.parseDouble(trimmed.substring(1)) / 100;
|
||||||
|
@ -1,261 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
package inr.numass.cryotemp;
|
|
||||||
|
|
||||||
import hep.dataforge.control.devices.Device;
|
|
||||||
import hep.dataforge.control.devices.DeviceListener;
|
|
||||||
import hep.dataforge.control.measurements.Measurement;
|
|
||||||
import hep.dataforge.control.measurements.MeasurementListener;
|
|
||||||
import hep.dataforge.exceptions.ControlException;
|
|
||||||
import hep.dataforge.fx.ConsoleFragment;
|
|
||||||
import hep.dataforge.io.MetaFileReader;
|
|
||||||
import hep.dataforge.meta.Meta;
|
|
||||||
import hep.dataforge.meta.MetaUtils;
|
|
||||||
import hep.dataforge.plots.PlotUtils;
|
|
||||||
import hep.dataforge.plots.data.TimePlottable;
|
|
||||||
import hep.dataforge.plots.data.TimePlottableGroup;
|
|
||||||
import hep.dataforge.plots.data.XYPlottable;
|
|
||||||
import hep.dataforge.plots.fx.FXPlotFrame;
|
|
||||||
import hep.dataforge.plots.fx.PlotContainer;
|
|
||||||
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
|
||||||
import hep.dataforge.values.Value;
|
|
||||||
import javafx.beans.InvalidationListener;
|
|
||||||
import javafx.beans.Observable;
|
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.control.ToggleButton;
|
|
||||||
import javafx.scene.layout.AnchorPane;
|
|
||||||
import javafx.stage.FileChooser;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FXML Controller class
|
|
||||||
*
|
|
||||||
* @author darksnake
|
|
||||||
*/
|
|
||||||
public class PKT8MainViewController implements Initializable, DeviceListener, MeasurementListener<PKT8Result>, AutoCloseable {
|
|
||||||
|
|
||||||
public static final String DEFAULT_CONFIG_LOCATION = "devices.xml";
|
|
||||||
ConsoleFragment consoleFragment;
|
|
||||||
private PKT8Device device;
|
|
||||||
private FXPlotFrame<XYPlottable> plotFrame;
|
|
||||||
private TimePlottableGroup plottables;
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ToggleButton startStopButton;
|
|
||||||
@FXML
|
|
||||||
private ToggleButton rawDataButton;
|
|
||||||
@FXML
|
|
||||||
private AnchorPane plotArea;
|
|
||||||
@FXML
|
|
||||||
private ToggleButton consoleButton;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws Exception {
|
|
||||||
if (device != null) {
|
|
||||||
device.shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the controller class.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
|
||||||
// setupPlotFrame(Meta.empty());
|
|
||||||
this.consoleFragment = new ConsoleFragment();
|
|
||||||
consoleFragment.bindTo(consoleButton);
|
|
||||||
rawDataButton.selectedProperty().addListener(new InvalidationListener() {
|
|
||||||
@Override
|
|
||||||
public void invalidated(Observable observable) {
|
|
||||||
if (plotFrame != null) {
|
|
||||||
setupPlotFrame(plotFrame.getConfig());
|
|
||||||
if (device != null) {
|
|
||||||
setupChannels();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startConfigDialog() throws IOException, ParseException, ControlException {
|
|
||||||
FileChooser fileChooser = new FileChooser();
|
|
||||||
fileChooser.setTitle("Open configuration 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("json", "*.json", "*.JSON"));
|
|
||||||
// fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("all", "*.*"));
|
|
||||||
File cfgFile = fileChooser.showOpenDialog(startStopButton.getScene().getWindow());
|
|
||||||
|
|
||||||
if (cfgFile != null) {
|
|
||||||
setConfig(MetaFileReader.read(cfgFile));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadTestConfig() throws ControlException {
|
|
||||||
try {
|
|
||||||
Meta testConfig = MetaFileReader
|
|
||||||
.read(new File(getClass().getResource("/config/defaultConfig.xml").toURI()));
|
|
||||||
setConfig(testConfig);
|
|
||||||
} catch (URISyntaxException | IOException | ParseException ex) {
|
|
||||||
throw new Error(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDeviceName() {
|
|
||||||
return "PKT8";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConfig(Meta config) throws ControlException {
|
|
||||||
if (config.hasNode("plotConfig")) {
|
|
||||||
Meta plotConfig = MetaUtils.findNodeByValue(config, "plotConfig", "device", getDeviceName());
|
|
||||||
if (plotConfig == null) {
|
|
||||||
plotConfig = config.getNode("plotConfig");
|
|
||||||
}
|
|
||||||
|
|
||||||
setupPlotFrame(plotConfig.getNode("plotFrame", Meta.empty()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.hasNode("device")) {
|
|
||||||
Meta deviceMeta = MetaUtils.findNodeByValue(config, "device", "name", Value.of(getDeviceName()));
|
|
||||||
setupDevice(deviceMeta);
|
|
||||||
} else {
|
|
||||||
setupDevice(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set o reset plot area
|
|
||||||
*/
|
|
||||||
private synchronized void setupPlotFrame(Meta plotFrameMeta) {
|
|
||||||
plottables = new TimePlottableGroup();
|
|
||||||
plottables.setMaxItems(plotFrameMeta.getInt("maxItems", 3000));
|
|
||||||
plottables.setMaxAge(Duration.parse(plotFrameMeta.getString("maxAge", "PT2H")));
|
|
||||||
plotArea.getChildren().clear();
|
|
||||||
plotFrame = new JFreeChartFrame(plotFrameMeta);
|
|
||||||
PlotUtils.setXAxis(plotFrame, "timestamp", null, "time");
|
|
||||||
PlotContainer container = PlotContainer.anchorTo(plotArea);
|
|
||||||
container.setPlot(plotFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupDevice(Meta deviceMeta) throws ControlException {
|
|
||||||
if (device != null) {
|
|
||||||
device.stopMeasurement(true);
|
|
||||||
device.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.device = new PKT8Device(deviceMeta.getString("port", "virtual"));
|
|
||||||
|
|
||||||
device.configure(deviceMeta);
|
|
||||||
|
|
||||||
device.addDeviceListener(this);
|
|
||||||
consoleFragment.addLogHandler(device.getLogger());
|
|
||||||
|
|
||||||
device.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupChannels() {
|
|
||||||
Collection<PKT8Channel> channels = this.device.getChanels();
|
|
||||||
|
|
||||||
//plot config from device configuration
|
|
||||||
//Do not use view config here, it is applyed separately
|
|
||||||
channels.stream()
|
|
||||||
.filter(channel -> !plottables.hasPlottable(channel.getName()))
|
|
||||||
.forEach(channel -> {
|
|
||||||
|
|
||||||
//plot config from device configuration
|
|
||||||
Meta deviceLineMeta = channel.meta().getNode("plot", channel.meta());
|
|
||||||
|
|
||||||
//Do not use view config here, it is applyed separately
|
|
||||||
TimePlottable plottable = new TimePlottable(channel.getName());
|
|
||||||
plottable.configure(deviceLineMeta);
|
|
||||||
plottables.addPlottable(plottable);
|
|
||||||
plotFrame.add(plottable);
|
|
||||||
});
|
|
||||||
plottables.applyConfig(plotFrame.getConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyDeviceInitialized(Device device) {
|
|
||||||
setupChannels();
|
|
||||||
startStopButton.setDisable(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyDeviceShutdown(Device device) {
|
|
||||||
startStopButton.setDisable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void onMeasurementResult(Measurement<PKT8Result> measurement, PKT8Result result, Instant time) {
|
|
||||||
//PENDING replace by connection?
|
|
||||||
if (rawDataButton.isSelected()) {
|
|
||||||
plottables.put(result.channel, result.rawValue);
|
|
||||||
} else {
|
|
||||||
plottables.put(result.channel, result.temperature);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMeasurementFailed(Measurement measurement, Throwable exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyDeviceStateChanged(Device device, String name, Value state) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void evaluateDeviceException(Device device, String message, Throwable exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private void onStartStopClick(ActionEvent event) {
|
|
||||||
if (device != null) {
|
|
||||||
try {
|
|
||||||
if (startStopButton.isSelected()) {
|
|
||||||
device.startMeasurement()
|
|
||||||
.addListener(this);
|
|
||||||
} else {
|
|
||||||
//in case device started
|
|
||||||
if (device.isMeasuring()) {
|
|
||||||
device.getMeasurement().removeListener(this);
|
|
||||||
device.stopMeasurement(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ControlException ex) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
|
import hep.dataforge.control.measurements.Measurement;
|
||||||
|
import hep.dataforge.control.measurements.MeasurementListener;
|
||||||
|
import hep.dataforge.meta.Meta;
|
||||||
|
import hep.dataforge.meta.MetaUtils;
|
||||||
|
import hep.dataforge.plots.PlotUtils;
|
||||||
|
import hep.dataforge.plots.data.TimePlottable;
|
||||||
|
import hep.dataforge.plots.data.TimePlottableGroup;
|
||||||
|
import hep.dataforge.plots.data.XYPlottable;
|
||||||
|
import hep.dataforge.plots.fx.FXPlotFrame;
|
||||||
|
import hep.dataforge.plots.fx.PlotContainer;
|
||||||
|
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.ToggleButton;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FXML Controller class
|
||||||
|
*
|
||||||
|
* @author darksnake
|
||||||
|
*/
|
||||||
|
public class PKT8PlotController implements Initializable, MeasurementListener<PKT8Result> {
|
||||||
|
|
||||||
|
private final PKT8Device device;
|
||||||
|
private FXPlotFrame<XYPlottable> plotFrame;
|
||||||
|
private TimePlottableGroup plottables;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ToggleButton rawDataButton;
|
||||||
|
@FXML
|
||||||
|
private AnchorPane plotArea;
|
||||||
|
|
||||||
|
public PKT8PlotController(PKT8Device device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the controller class.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initialize(URL url, ResourceBundle rb) {
|
||||||
|
rawDataButton.selectedProperty().addListener(observable -> {
|
||||||
|
if (plotFrame != null) {
|
||||||
|
setupPlotFrame(plotFrame.getConfig());
|
||||||
|
if (device != null) {
|
||||||
|
setupChannels();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
configure(device.getConfig());
|
||||||
|
setupChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceName() {
|
||||||
|
return device.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure(Meta config) {
|
||||||
|
if (config.hasNode("plotConfig")) {
|
||||||
|
Meta plotConfig = MetaUtils.findNodeByValue(config, "plotConfig", "device", getDeviceName());
|
||||||
|
if (plotConfig == null) {
|
||||||
|
plotConfig = config.getNode("plotConfig");
|
||||||
|
}
|
||||||
|
|
||||||
|
setupPlotFrame(plotConfig.getNode("plotFrame", Meta.empty()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set o reset plot area
|
||||||
|
*/
|
||||||
|
private synchronized void setupPlotFrame(Meta plotFrameMeta) {
|
||||||
|
plottables = new TimePlottableGroup();
|
||||||
|
plottables.setMaxItems(plotFrameMeta.getInt("maxItems", 3000));
|
||||||
|
plottables.setMaxAge(Duration.parse(plotFrameMeta.getString("maxAge", "PT2H")));
|
||||||
|
plotArea.getChildren().clear();
|
||||||
|
plotFrame = new JFreeChartFrame(plotFrameMeta);
|
||||||
|
PlotUtils.setXAxis(plotFrame, "timestamp", null, "time");
|
||||||
|
PlotContainer container = PlotContainer.anchorTo(plotArea);
|
||||||
|
container.setPlot(plotFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupChannels() {
|
||||||
|
Collection<PKT8Channel> channels = this.device.getChanels();
|
||||||
|
|
||||||
|
//plot config from device configuration
|
||||||
|
//Do not use view config here, it is applyed separately
|
||||||
|
channels.stream()
|
||||||
|
.filter(channel -> !plottables.hasPlottable(channel.getName()))
|
||||||
|
.forEach(channel -> {
|
||||||
|
|
||||||
|
//plot config from device configuration
|
||||||
|
Meta deviceLineMeta = channel.meta().getNode("plot", channel.meta());
|
||||||
|
|
||||||
|
//Do not use view config here, it is applyed separately
|
||||||
|
TimePlottable plottable = new TimePlottable(channel.getName());
|
||||||
|
plottable.configure(deviceLineMeta);
|
||||||
|
plottables.addPlottable(plottable);
|
||||||
|
plotFrame.add(plottable);
|
||||||
|
});
|
||||||
|
plottables.applyConfig(plotFrame.getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void onMeasurementResult(Measurement<PKT8Result> measurement, PKT8Result result, Instant time) {
|
||||||
|
//PENDING replace by connection?
|
||||||
|
if (rawDataButton.isSelected()) {
|
||||||
|
plottables.put(result.channel, result.rawValue);
|
||||||
|
} else {
|
||||||
|
plottables.put(result.channel, result.temperature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMeasurementFailed(Measurement measurement, Throwable exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
|
import hep.dataforge.fx.FXFragment;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.Window;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by darksnake on 07-Oct-16.
|
||||||
|
*/
|
||||||
|
public class PKT8PlotFragment extends FXFragment {
|
||||||
|
private final PKT8Device device;
|
||||||
|
private PKT8PlotController plotController;
|
||||||
|
|
||||||
|
public PKT8PlotFragment(PKT8Device device) {
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PKT8PlotFragment(Window window, PKT8Device device) {
|
||||||
|
super(window);
|
||||||
|
this.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Stage buildStage(Parent root) {
|
||||||
|
Stage stage = new Stage();
|
||||||
|
Scene scene = new Scene(root, 600, 400);
|
||||||
|
|
||||||
|
|
||||||
|
stage.setTitle("PKT8 cryogenic temperature viewer");
|
||||||
|
stage.setScene(scene);
|
||||||
|
stage.setMinHeight(400);
|
||||||
|
stage.setMinWidth(600);
|
||||||
|
stage.sizeToScene();
|
||||||
|
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Parent getRoot() {
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Plot.fxml"));
|
||||||
|
plotController = new PKT8PlotController(device);
|
||||||
|
loader.setController(plotController);
|
||||||
|
try {
|
||||||
|
return loader.load();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onShow() {
|
||||||
|
super.onShow();
|
||||||
|
if (device.isMeasuring()) {
|
||||||
|
device.getMeasurement().addListener(plotController);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onHide() {
|
||||||
|
super.onHide();
|
||||||
|
if (device.isMeasuring()) {
|
||||||
|
device.getMeasurement().removeListener(plotController);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -31,4 +31,15 @@ public class PKT8Result {
|
|||||||
this.temperature = temperature;
|
this.temperature = temperature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRawString() {
|
||||||
|
return String.format("%.2f", rawValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemperatureString() {
|
||||||
|
return String.format("%.2f", temperature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.scene.text.Font?>
|
||||||
|
<BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="400.0"
|
||||||
|
xmlns="http://javafx.com/javafx/8.0.60">
|
||||||
|
<center>
|
||||||
|
<TableView fx:id="table" BorderPane.alignment="CENTER">
|
||||||
|
<columns>
|
||||||
|
<TableColumn fx:id="sensorColumn" prefWidth="75.0" text="Sensor"/>
|
||||||
|
<TableColumn fx:id="resColumn" prefWidth="75.0" text="Resistance"/>
|
||||||
|
<TableColumn fx:id="tempColumn" prefWidth="116.0" text="Temperature"/>
|
||||||
|
</columns>
|
||||||
|
<columnResizePolicy>
|
||||||
|
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
|
||||||
|
</columnResizePolicy>
|
||||||
|
</TableView>
|
||||||
|
</center>
|
||||||
|
<top>
|
||||||
|
<ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
|
||||||
|
<items>
|
||||||
|
<ToggleButton fx:id="startStopButton" mnemonicParsing="false" onAction="#onStartStopClick"
|
||||||
|
text="Start"/>
|
||||||
|
<Separator orientation="VERTICAL"/>
|
||||||
|
<Pane HBox.hgrow="ALWAYS"/>
|
||||||
|
<Separator orientation="VERTICAL"/>
|
||||||
|
<ToggleButton fx:id="plotButton" mnemonicParsing="false" text="Plot"/>
|
||||||
|
<ToggleButton fx:id="consoleButton" mnemonicParsing="false" text="Console"/>
|
||||||
|
</items>
|
||||||
|
</ToolBar>
|
||||||
|
</top>
|
||||||
|
<bottom>
|
||||||
|
<ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
|
||||||
|
<items>
|
||||||
|
<Label text="Last update: "/>
|
||||||
|
<Label fx:id="lastUpdateLabel" text="NONE">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="12.0"/>
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</items>
|
||||||
|
</ToolBar>
|
||||||
|
</bottom>
|
||||||
|
</BorderPane>
|
@ -16,23 +16,22 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.Separator?>
|
||||||
|
<?import javafx.scene.control.ToggleButton?>
|
||||||
|
<?import javafx.scene.control.ToolBar?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<BorderPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60"
|
<BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="600.0" prefWidth="800.0"
|
||||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.cryotemp.PKT8MainViewController">
|
xmlns="http://javafx.com/javafx/8.0.60">
|
||||||
<center>
|
<center>
|
||||||
<AnchorPane fx:id="plotArea"/>
|
<AnchorPane fx:id="plotArea"/>
|
||||||
</center>
|
</center>
|
||||||
<top>
|
<top>
|
||||||
<ToolBar BorderPane.alignment="CENTER">
|
<ToolBar BorderPane.alignment="CENTER">
|
||||||
<items>
|
<items>
|
||||||
<ToggleButton fx:id="startStopButton" disable="true" mnemonicParsing="false"
|
|
||||||
onAction="#onStartStopClick" prefWidth="50.0" text="Start"/>
|
|
||||||
<ToggleButton fx:id="rawDataButton" mnemonicParsing="false" text="Raw data"/>
|
<ToggleButton fx:id="rawDataButton" mnemonicParsing="false" text="Raw data"/>
|
||||||
<Separator orientation="VERTICAL"/>
|
<Separator orientation="VERTICAL"/>
|
||||||
<Pane HBox.hgrow = "ALWAYS"/>
|
<Pane HBox.hgrow="ALWAYS"/>
|
||||||
<Separator orientation="VERTICAL"/>
|
<Separator orientation="VERTICAL"/>
|
||||||
<ToggleButton fx:id="consoleButton" contentDisplay="CENTER" mnemonicParsing="false" text="Console"/>
|
|
||||||
</items>
|
</items>
|
||||||
</ToolBar>
|
</ToolBar>
|
||||||
</top>
|
</top>
|
@ -20,7 +20,7 @@ import inr.numass.server.NumassServer
|
|||||||
import inr.numass.storage.NumassStorage
|
import inr.numass.storage.NumassStorage
|
||||||
import org.apache.commons.vfs2.FileObject
|
import org.apache.commons.vfs2.FileObject
|
||||||
|
|
||||||
String path = "D:\\temp\\test\\numass-server\\"
|
String path = "D:\\temp\\test\\numass\\"
|
||||||
|
|
||||||
FileObject file = VFSUtils.getLocalFile(new File(path))
|
FileObject file = VFSUtils.getLocalFile(new File(path))
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public class NumassStorageHandler extends StorageRatpackHandler {
|
|||||||
|
|
||||||
List<String> notes = getNotes(noteLoader).limit(100).map(note -> render(note)).collect(Collectors.toList());
|
List<String> notes = getNotes(noteLoader).limit(100).map(note -> render(note)).collect(Collectors.toList());
|
||||||
|
|
||||||
Map data = new HashMap(2);
|
Map<String, Object> data = new HashMap<>(2);
|
||||||
data.put("notes", notes);
|
data.put("notes", notes);
|
||||||
|
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
|
Loading…
Reference in New Issue
Block a user