Cryotemp and server update
This commit is contained in:
parent
dcf318b16c
commit
ac312b7671
@ -2,6 +2,7 @@ package inr.numass.control
|
|||||||
|
|
||||||
import hep.dataforge.control.devices.Device
|
import hep.dataforge.control.devices.Device
|
||||||
import hep.dataforge.fx.FXObject
|
import hep.dataforge.fx.FXObject
|
||||||
|
import hep.dataforge.fx.fragments.FXFragment
|
||||||
import hep.dataforge.fx.fragments.FragmentWindow
|
import hep.dataforge.fx.fragments.FragmentWindow
|
||||||
import javafx.beans.property.SimpleObjectProperty
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
@ -29,7 +30,7 @@ class DeviceInfoView(val device: Device, node: Node? = null) : Fragment(device.n
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
FragmentWindow(hep.dataforge.fx.fragments.Fragment.buildFromNode(device.name) { deviceNode.get() })
|
FragmentWindow(FXFragment.buildFromNode(device.name) { deviceNode.get() })
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
deviceNode.set(node);
|
deviceNode.set(node);
|
||||||
|
@ -15,130 +15,137 @@
|
|||||||
*/
|
*/
|
||||||
package inr.numass.cryotemp;
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
import ch.qos.logback.classic.Level;
|
import hep.dataforge.control.devices.DeviceFactory;
|
||||||
import hep.dataforge.exceptions.ControlException;
|
|
||||||
import hep.dataforge.io.MetaFileReader;
|
|
||||||
import hep.dataforge.meta.Meta;
|
import hep.dataforge.meta.Meta;
|
||||||
import hep.dataforge.meta.MetaUtils;
|
import inr.numass.control.DeviceViewConnection;
|
||||||
import hep.dataforge.storage.commons.StorageManager;
|
import inr.numass.control.NumassControlApplication;
|
||||||
import inr.numass.control.NumassControlUtils;
|
|
||||||
import javafx.application.Application;
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.fxml.FXMLLoader;
|
|
||||||
import javafx.scene.Parent;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.util.Objects;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
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 NumassControlApplication<PKT8Device> {
|
||||||
|
@Override
|
||||||
public static final String DEFAULT_CONFIG_LOCATION = "numass-devices.xml";
|
protected DeviceViewConnection<PKT8Device> buildView() {
|
||||||
|
return PKT8View.build();
|
||||||
|
|
||||||
PKT8Device device;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param args the command line arguments
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
launch(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws IOException, ControlException, ParseException {
|
protected DeviceFactory<PKT8Device> getDeviceFactory() {
|
||||||
// Locale.setDefault(Locale.US);// чтобы отделение десятичных знаков было точкой
|
return new PKT8DeviceFactory();
|
||||||
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("config", DEFAULT_CONFIG_LOCATION)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
device = setupDevice(deviceName, config);
|
|
||||||
|
|
||||||
// setting up storage connections
|
|
||||||
NumassControlUtils.connectStorage(device, config);
|
|
||||||
|
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Indicator.fxml"));
|
|
||||||
PKT8Controller controller = new PKT8Controller();
|
|
||||||
device.connect(controller, "view");
|
|
||||||
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();
|
|
||||||
} 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.hasMeta("device")) {
|
|
||||||
deviceMeta = MetaUtils.findNodeByValue(config, "device", "name", deviceName);
|
|
||||||
} else {
|
|
||||||
deviceMeta = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
PKT8Device device = new PKT8Device();
|
|
||||||
device.configure(deviceMeta);
|
|
||||||
|
|
||||||
if(!deviceMeta.hasValue(PORT_NAME_KEY)){
|
|
||||||
device.getLogger().warn("Port name not provided, will try to use emulation port");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() throws Exception {
|
protected void setupStage(Stage stage, PKT8Device device) {
|
||||||
super.stop();
|
stage.setTitle("Numass temperature view " + device.getName());
|
||||||
if (device != null) {
|
stage.setMinHeight(400);
|
||||||
device.shutdown();
|
stage.setMinWidth(400);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean acceptDevice(Meta meta) {
|
||||||
|
return Objects.equals(meta.getString("type"), "PKT8");
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static final String DEFAULT_CONFIG_LOCATION = "numass-devices.xml";
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// PKT8Device device;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @param args the command line arguments
|
||||||
|
// */
|
||||||
|
// public static void main(String[] args) {
|
||||||
|
// launch(args);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @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("config", DEFAULT_CONFIG_LOCATION)));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// device = setupDevice(deviceName, config);
|
||||||
|
//
|
||||||
|
// // setting up storage connections
|
||||||
|
// NumassControlUtils.connectStorage(device, config);
|
||||||
|
//
|
||||||
|
// FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Indicator.fxml"));
|
||||||
|
// PKT8View controller = new PKT8View();
|
||||||
|
// device.connect(controller, "view");
|
||||||
|
// 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();
|
||||||
|
// } 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.hasMeta("device")) {
|
||||||
|
// deviceMeta = MetaUtils.findNodeByValue(config, "device", "name", deviceName);
|
||||||
|
// } else {
|
||||||
|
// deviceMeta = config;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// PKT8Device device = new PKT8Device();
|
||||||
|
// device.configure(deviceMeta);
|
||||||
|
//
|
||||||
|
// if(!deviceMeta.hasValue(PORT_NAME_KEY)){
|
||||||
|
// device.getLogger().warn("Port name not provided, will try to use emulation port");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// return device;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void stop() throws Exception {
|
||||||
|
// super.stop();
|
||||||
|
// if (device != null) {
|
||||||
|
// device.shutdown();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ package inr.numass.cryotemp;
|
|||||||
|
|
||||||
import hep.dataforge.context.Context;
|
import hep.dataforge.context.Context;
|
||||||
import hep.dataforge.control.collectors.RegularPointCollector;
|
import hep.dataforge.control.collectors.RegularPointCollector;
|
||||||
|
import hep.dataforge.control.connections.Connection;
|
||||||
import hep.dataforge.control.connections.LoaderConnection;
|
import hep.dataforge.control.connections.LoaderConnection;
|
||||||
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;
|
||||||
@ -37,12 +37,14 @@ import hep.dataforge.storage.api.Storage;
|
|||||||
import hep.dataforge.storage.commons.LoaderFactory;
|
import hep.dataforge.storage.commons.LoaderFactory;
|
||||||
import hep.dataforge.tables.DataPoint;
|
import hep.dataforge.tables.DataPoint;
|
||||||
import hep.dataforge.tables.PointListener;
|
import hep.dataforge.tables.PointListener;
|
||||||
|
import hep.dataforge.tables.TableFormat;
|
||||||
import hep.dataforge.tables.TableFormatBuilder;
|
import hep.dataforge.tables.TableFormatBuilder;
|
||||||
import hep.dataforge.utils.DateTimeUtils;
|
import hep.dataforge.utils.DateTimeUtils;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
import java.util.stream.Collectors;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A device controller for Dubna PKT 8 cryogenic thermometry device
|
* A device controller for Dubna PKT 8 cryogenic thermometry device
|
||||||
@ -51,7 +53,7 @@ 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)
|
@RoleDef(name = Roles.VIEW_ROLE, objectType = PKT8View.class)
|
||||||
@ValueDef(name = "port", def = "virtual", info = "The name of the port for this PKT8")
|
@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 PKT8_DEVICE_TYPE = "numass:pkt8";
|
||||||
@ -66,6 +68,11 @@ 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached values
|
||||||
|
*/
|
||||||
|
private TableFormat format;
|
||||||
|
|
||||||
public PKT8Device() {
|
public PKT8Device() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,8 +115,47 @@ 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));
|
||||||
|
|
||||||
setupLoaders();
|
// setting up the collector
|
||||||
|
Duration duration = Duration.parse(meta().getString("averagingDuration", "PT30S"));
|
||||||
|
collector = new RegularPointCollector((DataPoint dp) -> {
|
||||||
|
forEachConnection(Roles.POINT_LISTENER_ROLE, PointListener.class, listener -> {
|
||||||
|
getLogger().debug("Point measurement complete. Pushing...");
|
||||||
|
listener.accept(dp);
|
||||||
|
});
|
||||||
|
}, duration, channels.values().stream().map(PKT8Channel::getName).toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private TableFormat getTableFormat() {
|
||||||
|
if (format == null) {
|
||||||
|
// Building data format
|
||||||
|
TableFormatBuilder tableFormatBuilder = new TableFormatBuilder()
|
||||||
|
.addTime("timestamp");
|
||||||
|
|
||||||
|
for (PKT8Channel channel : channels.values()) {
|
||||||
|
tableFormatBuilder.addNumber(channel.getName());
|
||||||
|
}
|
||||||
|
format = tableFormatBuilder.build();
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void connect(Connection connection, String... roles) {
|
||||||
|
super.connect(connection, roles);
|
||||||
|
if (connection instanceof StorageConnection) {
|
||||||
|
//TODO add loader cache to remove loaders on disconnect
|
||||||
|
Storage storage = ((StorageConnection) connection).getStorage();
|
||||||
|
String suffix = DateTimeUtils.fileSuffix();
|
||||||
|
|
||||||
|
try {
|
||||||
|
PointLoader pointLoader = LoaderFactory.buildPointLoder(storage,
|
||||||
|
"cryotemp_" + suffix, "", "timestamp", getTableFormat());
|
||||||
|
this.connect(new LoaderConnection(pointLoader), Roles.POINT_LISTENER_ROLE);
|
||||||
|
} catch (StorageException e) {
|
||||||
|
getLogger().error("Failed to build loader from storage {}", storage.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -253,50 +299,9 @@ public class PKT8Device extends PortSensor<PKT8Result> {
|
|||||||
return getState(ABUF).stringValue();
|
return getState(ABUF).stringValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupLoaders() {
|
// public void connectPointListener(PointListenerConnection listener) {
|
||||||
|
// this.connect(listener, Roles.POINT_LISTENER_ROLE);
|
||||||
// Building data format
|
// }
|
||||||
TableFormatBuilder tableFormatBuilder = new TableFormatBuilder()
|
|
||||||
.addTime("timestamp");
|
|
||||||
List<String> names = new ArrayList<>();
|
|
||||||
|
|
||||||
for (PKT8Channel channel : channels.values()) {
|
|
||||||
tableFormatBuilder.addNumber(channel.getName());
|
|
||||||
names.add(channel.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// setting up loader for each of storages
|
|
||||||
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 = Long.toString(DateTimeUtils.now().toEpochMilli());
|
|
||||||
|
|
||||||
PointLoader pointLoader = null;
|
|
||||||
try {
|
|
||||||
pointLoader = LoaderFactory.buildPointLoder(storage,
|
|
||||||
"cryotemp_" + suffix, "", "timestamp", tableFormatBuilder.build());
|
|
||||||
this.connect(new LoaderConnection(pointLoader), Roles.POINT_LISTENER_ROLE);
|
|
||||||
} catch (StorageException e) {
|
|
||||||
getLogger().error("Failed to build loader from storage {}", storage.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// setting up the collector
|
|
||||||
Duration duration = Duration.parse(meta().getString("averagingDuration", "PT30S"));
|
|
||||||
collector = new RegularPointCollector((DataPoint dp) -> {
|
|
||||||
forEachConnection(Roles.POINT_LISTENER_ROLE, PointListener.class, listener -> {
|
|
||||||
getLogger().debug("Point measurement complete. Pushing...");
|
|
||||||
listener.accept(dp);
|
|
||||||
});
|
|
||||||
}, duration, names);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connectPointListener(PointListenerConnection listener) {
|
|
||||||
this.connect(listener, Roles.POINT_LISTENER_ROLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Measurement<PKT8Result> createMeasurement() throws MeasurementException {
|
protected Measurement<PKT8Result> createMeasurement() throws MeasurementException {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package inr.numass.cryotemp;
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
import hep.dataforge.fx.fragments.Fragment;
|
import hep.dataforge.control.connections.Roles;
|
||||||
|
import hep.dataforge.fx.fragments.FXFragment;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
|
|
||||||
@ -9,13 +10,22 @@ import java.io.IOException;
|
|||||||
/**
|
/**
|
||||||
* Created by darksnake on 07-Oct-16.
|
* Created by darksnake on 07-Oct-16.
|
||||||
*/
|
*/
|
||||||
public class PKT8PlotFragment extends Fragment {
|
public class PKT8PlotFragment extends FXFragment {
|
||||||
private final PKT8Device device;
|
private PKT8PlotView plotController;
|
||||||
private PKT8PlotController plotController;
|
|
||||||
|
|
||||||
public PKT8PlotFragment(PKT8Device device) {
|
public PKT8PlotFragment(PKT8Device device) {
|
||||||
super("PKT8 cryogenic temperature viewer", 600, 400);
|
super("PKT8 cryogenic temperature viewer", 600, 400);
|
||||||
this.device = device;
|
|
||||||
|
try {
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Plot.fxml"));
|
||||||
|
loader.load();
|
||||||
|
plotController = loader.getController();
|
||||||
|
device.connect(plotController, Roles.VIEW_ROLE);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
showingProperty().addListener((observable, oldValue, newValue) -> {
|
showingProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
if (device.isMeasuring()) {
|
if (device.isMeasuring()) {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
@ -29,13 +39,6 @@ public class PKT8PlotFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Parent buildRoot() {
|
protected Parent buildRoot() {
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Plot.fxml"));
|
return plotController.getPane();
|
||||||
plotController = new PKT8PlotController(device);
|
|
||||||
loader.setController(plotController);
|
|
||||||
try {
|
|
||||||
return loader.load();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,19 @@ package inr.numass.cryotemp;
|
|||||||
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;
|
||||||
import hep.dataforge.meta.MetaUtils;
|
|
||||||
import hep.dataforge.plots.PlotUtils;
|
import hep.dataforge.plots.PlotUtils;
|
||||||
import hep.dataforge.plots.data.TimePlottable;
|
import hep.dataforge.plots.data.TimePlottable;
|
||||||
import hep.dataforge.plots.data.TimePlottableGroup;
|
import hep.dataforge.plots.data.TimePlottableGroup;
|
||||||
import hep.dataforge.plots.fx.FXPlotFrame;
|
import hep.dataforge.plots.fx.FXPlotFrame;
|
||||||
import hep.dataforge.plots.fx.PlotContainer;
|
import hep.dataforge.plots.fx.PlotContainer;
|
||||||
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
||||||
|
import inr.numass.control.DeviceViewConnection;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.ToggleButton;
|
import javafx.scene.control.ToggleButton;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -41,53 +43,47 @@ import java.util.ResourceBundle;
|
|||||||
*
|
*
|
||||||
* @author darksnake
|
* @author darksnake
|
||||||
*/
|
*/
|
||||||
public class PKT8PlotController implements Initializable, MeasurementListener<PKT8Result> {
|
public class PKT8PlotView extends DeviceViewConnection<PKT8Device> implements Initializable, MeasurementListener<PKT8Result> {
|
||||||
|
|
||||||
private final PKT8Device device;
|
|
||||||
private FXPlotFrame plotFrame;
|
private FXPlotFrame plotFrame;
|
||||||
private TimePlottableGroup plottables;
|
private TimePlottableGroup plottables;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private BorderPane root;
|
||||||
@FXML
|
@FXML
|
||||||
private ToggleButton rawDataButton;
|
private ToggleButton rawDataButton;
|
||||||
@FXML
|
@FXML
|
||||||
private AnchorPane plotArea;
|
private AnchorPane plotArea;
|
||||||
|
|
||||||
public PKT8PlotController(PKT8Device device) {
|
|
||||||
this.device = device;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the controller class.
|
* Initializes the controller class.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
public void initialize(URL url, ResourceBundle rb) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void open(PKT8Device device) throws Exception {
|
||||||
|
super.open(device);
|
||||||
rawDataButton.selectedProperty().addListener(observable -> {
|
rawDataButton.selectedProperty().addListener(observable -> {
|
||||||
if (plotFrame != null) {
|
if (plotFrame != null) {
|
||||||
setupPlotFrame(plotFrame.getConfig());
|
setupPlotFrame(plotFrame.getConfig());
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
setupChannels();
|
setupChannels(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
configure(device.getConfig());
|
setupPlotFrame(device.meta().getMetaOrEmpty("plot.frame"));
|
||||||
setupChannels();
|
setupChannels(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDeviceName() {
|
@Override
|
||||||
return device.getName();
|
public void close() throws Exception {
|
||||||
|
super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configure(Meta config) {
|
|
||||||
if (config.hasMeta("plotConfig")) {
|
|
||||||
Meta plotConfig = MetaUtils.findNodeByValue(config, "plotConfig", "device", getDeviceName());
|
|
||||||
if (plotConfig == null) {
|
|
||||||
plotConfig = config.getMeta("plotConfig");
|
|
||||||
}
|
|
||||||
|
|
||||||
setupPlotFrame(plotConfig.getMeta("plotFrame", Meta.empty()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set o reset plot area
|
* Set o reset plot area
|
||||||
@ -102,23 +98,17 @@ public class PKT8PlotController implements Initializable, MeasurementListener<PK
|
|||||||
container.setPlot(plotFrame);
|
container.setPlot(plotFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupChannels() {
|
private void setupChannels(PKT8Device device) {
|
||||||
Collection<PKT8Channel> channels = this.device.getChanels();
|
Collection<PKT8Channel> channels = device.getChanels();
|
||||||
|
|
||||||
//plot config from device configuration
|
//plot config from device configuration
|
||||||
//Do not use view config here, it is applyed separately
|
//Do not use view config here, it is applyed separately
|
||||||
channels.stream()
|
channels.stream()
|
||||||
.filter(channel -> !plottables.has(channel.getName()))
|
.filter(channel -> !plottables.has(channel.getName()))
|
||||||
.forEach(channel -> {
|
.forEach(channel -> {
|
||||||
|
|
||||||
//plot config from device configuration
|
//plot config from device configuration
|
||||||
Meta deviceLineMeta = channel.meta().getMeta("plot", channel.meta());
|
|
||||||
|
|
||||||
//Do not use view config here, it is applyed separately
|
|
||||||
TimePlottable plottable = new TimePlottable(channel.getName());
|
TimePlottable plottable = new TimePlottable(channel.getName());
|
||||||
if (deviceLineMeta.hasMeta("plot")) {
|
plottable.configure(channel.meta());
|
||||||
plottable.configure(deviceLineMeta.getMeta("plot"));
|
|
||||||
}
|
|
||||||
plottables.add(plottable);
|
plottables.add(plottable);
|
||||||
plotFrame.add(plottable);
|
plotFrame.add(plottable);
|
||||||
});
|
});
|
||||||
@ -146,4 +136,8 @@ public class PKT8PlotController implements Initializable, MeasurementListener<PK
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getFXNode() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,23 +1,27 @@
|
|||||||
package inr.numass.cryotemp;
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
import hep.dataforge.control.connections.DeviceConnection;
|
|
||||||
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.exceptions.ControlException;
|
import hep.dataforge.exceptions.ControlException;
|
||||||
import hep.dataforge.exceptions.MeasurementException;
|
import hep.dataforge.exceptions.MeasurementException;
|
||||||
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 inr.numass.control.DeviceViewConnection;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.TableColumn;
|
import javafx.scene.control.TableColumn;
|
||||||
import javafx.scene.control.TableView;
|
import javafx.scene.control.TableView;
|
||||||
import javafx.scene.control.ToggleButton;
|
import javafx.scene.control.ToggleButton;
|
||||||
import javafx.scene.control.cell.PropertyValueFactory;
|
import javafx.scene.control.cell.PropertyValueFactory;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
@ -25,11 +29,23 @@ import java.util.ResourceBundle;
|
|||||||
/**
|
/**
|
||||||
* Created by darksnake on 07-Oct-16.
|
* Created by darksnake on 07-Oct-16.
|
||||||
*/
|
*/
|
||||||
public class PKT8Controller extends DeviceConnection<PKT8Device> implements Initializable, DeviceListener, MeasurementListener<PKT8Result> {
|
public class PKT8View extends DeviceViewConnection<PKT8Device> implements Initializable, MeasurementListener<PKT8Result> {
|
||||||
|
|
||||||
|
public static PKT8View build(){
|
||||||
|
try {
|
||||||
|
FXMLLoader loader = new FXMLLoader(PKT8View.class.getResource("/fxml/PKT8Indicator.fxml"));
|
||||||
|
loader.load();
|
||||||
|
return loader.getController();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private LogFragment logFragment;
|
private LogFragment logFragment;
|
||||||
private PKT8PlotFragment plotFragment;
|
private PKT8PlotFragment plotFragment;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private BorderPane root;
|
||||||
@FXML
|
@FXML
|
||||||
private ToggleButton startStopButton;
|
private ToggleButton startStopButton;
|
||||||
@FXML
|
@FXML
|
||||||
@ -38,7 +54,6 @@ public class PKT8Controller extends DeviceConnection<PKT8Device> implements Init
|
|||||||
private ToggleButton plotButton;
|
private ToggleButton plotButton;
|
||||||
@FXML
|
@FXML
|
||||||
private Label lastUpdateLabel;
|
private Label lastUpdateLabel;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableView<PKT8Result> table;
|
private TableView<PKT8Result> table;
|
||||||
@FXML
|
@FXML
|
||||||
@ -51,18 +66,30 @@ public class PKT8Controller extends DeviceConnection<PKT8Device> implements Init
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
this.logFragment = new LogFragment();
|
|
||||||
logFragment.addLogHandler(getDevice().getContext().getLogger());
|
|
||||||
//TODO to be removed later
|
|
||||||
logFragment.hookStd();
|
|
||||||
new FragmentWindow(logFragment).bindTo(consoleButton);
|
|
||||||
plotFragment = new PKT8PlotFragment(getDevice());
|
|
||||||
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void open(@NotNull PKT8Device device) throws Exception {
|
||||||
|
super.open(device);
|
||||||
|
this.logFragment = new LogFragment();
|
||||||
|
logFragment.addLogHandler(device.getContext().getLogger());
|
||||||
|
logFragment.hookStd();//TODO to be removed later
|
||||||
|
|
||||||
|
plotFragment = new PKT8PlotFragment(device);
|
||||||
startStopButton.selectedProperty().setValue(getDevice().isMeasuring());
|
startStopButton.selectedProperty().setValue(getDevice().isMeasuring());
|
||||||
|
|
||||||
|
new FragmentWindow(logFragment).bindTo(consoleButton);
|
||||||
|
new FragmentWindow(plotFragment).bindTo(plotButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
super.close();
|
||||||
|
logFragment = null;
|
||||||
|
plotFragment = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -108,4 +135,9 @@ public class PKT8Controller extends DeviceConnection<PKT8Device> implements Init
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getFXNode() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<device>
|
|
||||||
<storage path="D:\\temp\\cryo"/>
|
|
||||||
<!--<connection ip="192.168.111.137" port="4001"/>-->
|
|
||||||
<abuf>120</abuf>
|
|
||||||
<channel designation="a" name="a-channel" r0="1000" transformationType="hyperbolic" coefs="[1.0,1.0]"
|
|
||||||
color="black"/>
|
|
||||||
<channel designation="b" name="b-channel" r0="1000" transformationType="hyperbolic" coefs="[1.1,1.1]"/>
|
|
||||||
<channel designation="c" name="c-channel" r0="1000" transformationType="hyperbolic" coefs="[1.2,1.0]"
|
|
||||||
thickness="2"/>
|
|
||||||
<channel designation="d" name="d-channel" r0="1000" transformationType="hyperbolic" coefs="[1.3,1.0]"/>
|
|
||||||
<plotConfig>
|
|
||||||
<eachPlot thickness="4"/>
|
|
||||||
<plot name="c-channel" color="magenta"/>
|
|
||||||
</plotConfig>
|
|
||||||
</device>
|
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<config>
|
||||||
|
<storage path="D:/temp/test"/>
|
||||||
|
<device type="PKT8">
|
||||||
|
<!--<connection ip="192.168.111.137" port="4001"/>-->
|
||||||
|
<abuf>120</abuf>
|
||||||
|
<channel designation="a" name="a-channel" r0="1000" transformationType="hyperbolic" coefs="[1.0,1.0]"
|
||||||
|
color="black"/>
|
||||||
|
<channel designation="b" name="b-channel" r0="1000" transformationType="hyperbolic" coefs="[1.1,1.1]"/>
|
||||||
|
<channel designation="c" name="c-channel" r0="1000" transformationType="hyperbolic" coefs="[1.2,1.0]"
|
||||||
|
thickness="2"/>
|
||||||
|
<channel designation="d" name="d-channel" r0="1000" transformationType="hyperbolic" coefs="[1.3,1.0]"/>
|
||||||
|
<plotConfig>
|
||||||
|
<eachPlot thickness="4"/>
|
||||||
|
<plot name="c-channel" color="magenta"/>
|
||||||
|
</plotConfig>
|
||||||
|
</device>
|
||||||
|
</config>
|
@ -1,7 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<device>
|
<config>
|
||||||
<!-- Device configuration -->
|
|
||||||
<storage path="D:\\temp\\cryo"/>
|
<storage path="D:\\temp\\cryo"/>
|
||||||
|
<device type="PKT8" name="thermo-1">
|
||||||
|
<!-- Device configuration -->
|
||||||
<port>192.168.111.36:4001</port>
|
<port>192.168.111.36:4001</port>
|
||||||
<abuf>1</abuf>
|
<abuf>1</abuf>
|
||||||
<averagingDuration>"PT60S"</averagingDuration>
|
<averagingDuration>"PT60S"</averagingDuration>
|
||||||
@ -29,3 +30,4 @@
|
|||||||
<eachPlot thickness="3"/>
|
<eachPlot thickness="3"/>
|
||||||
</plotConfig>
|
</plotConfig>
|
||||||
</device>
|
</device>
|
||||||
|
</config>
|
@ -3,8 +3,8 @@
|
|||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
<BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="400.0"
|
<BorderPane fx:id="root" xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="400.0"
|
||||||
xmlns="http://javafx.com/javafx/8.0.60">
|
xmlns="http://javafx.com/javafx/8.0.111" fx:controller="inr.numass.cryotemp.PKT8View">
|
||||||
<center>
|
<center>
|
||||||
<TableView fx:id="table" BorderPane.alignment="CENTER">
|
<TableView fx:id="table" BorderPane.alignment="CENTER">
|
||||||
<columns>
|
<columns>
|
||||||
|
@ -20,8 +20,8 @@ limitations under the License.
|
|||||||
<?import javafx.scene.control.ToggleButton?>
|
<?import javafx.scene.control.ToggleButton?>
|
||||||
<?import javafx.scene.control.ToolBar?>
|
<?import javafx.scene.control.ToolBar?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<BorderPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="600.0" prefWidth="800.0"
|
<BorderPane fx:id="root" xmlns:fx="http://javafx.com/fxml/1" prefHeight="600.0" prefWidth="800.0"
|
||||||
xmlns="http://javafx.com/javafx/8.0.60">
|
xmlns="http://javafx.com/javafx/8.0.111" fx:controller="inr.numass.cryotemp.PKT8PlotView">
|
||||||
<center>
|
<center>
|
||||||
<AnchorPane fx:id="plotArea"/>
|
<AnchorPane fx:id="plotArea"/>
|
||||||
</center>
|
</center>
|
||||||
|
@ -428,7 +428,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
|
|||||||
|
|
||||||
TableFormat format = builder.build();
|
TableFormat format = builder.build();
|
||||||
|
|
||||||
String suffix = DateTimeUtils.now().toString();
|
String suffix = DateTimeUtils.fileSuffix();
|
||||||
return LoaderFactory
|
return LoaderFactory
|
||||||
.buildPointLoder(storage, "msp_" + suffix, "", "timestamp", format);
|
.buildPointLoder(storage, "msp_" + suffix, "", "timestamp", format);
|
||||||
} catch (StorageException ex) {
|
} catch (StorageException ex) {
|
||||||
|
@ -16,12 +16,15 @@
|
|||||||
package inr.numass.control.msp.fx;
|
package inr.numass.control.msp.fx;
|
||||||
|
|
||||||
import hep.dataforge.control.devices.DeviceFactory;
|
import hep.dataforge.control.devices.DeviceFactory;
|
||||||
|
import hep.dataforge.meta.Meta;
|
||||||
import inr.numass.control.DeviceViewConnection;
|
import inr.numass.control.DeviceViewConnection;
|
||||||
import inr.numass.control.NumassControlApplication;
|
import inr.numass.control.NumassControlApplication;
|
||||||
import inr.numass.control.msp.MspDevice;
|
import inr.numass.control.msp.MspDevice;
|
||||||
import inr.numass.control.msp.MspDeviceFactory;
|
import inr.numass.control.msp.MspDeviceFactory;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author darksnake
|
* @author darksnake
|
||||||
*/
|
*/
|
||||||
@ -38,12 +41,17 @@ public class MspApp extends NumassControlApplication<MspDevice> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupStage(Stage stage) {
|
protected void setupStage(Stage stage, MspDevice device) {
|
||||||
stage.setTitle("Numass mass-spectrometer view");
|
stage.setTitle("Numass mass-spectrometer view");
|
||||||
stage.setMinHeight(400);
|
stage.setMinHeight(400);
|
||||||
stage.setMinWidth(600);
|
stage.setMinWidth(600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean acceptDevice(Meta meta) {
|
||||||
|
return Objects.equals(meta.getString("name"), "msp");
|
||||||
|
}
|
||||||
|
|
||||||
// private Device device;
|
// private Device device;
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package inr.numass.control.msp.fx;
|
package inr.numass.control.msp.fx;
|
||||||
|
|
||||||
import hep.dataforge.control.devices.Device;
|
|
||||||
import hep.dataforge.control.devices.DeviceListener;
|
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;
|
||||||
@ -24,8 +23,8 @@ import hep.dataforge.fx.fragments.LogFragment;
|
|||||||
import hep.dataforge.meta.ConfigChangeListener;
|
import hep.dataforge.meta.ConfigChangeListener;
|
||||||
import hep.dataforge.meta.Meta;
|
import hep.dataforge.meta.Meta;
|
||||||
import hep.dataforge.meta.MetaBuilder;
|
import hep.dataforge.meta.MetaBuilder;
|
||||||
import hep.dataforge.plots.data.PlottableGroup;
|
|
||||||
import hep.dataforge.plots.data.TimePlottable;
|
import hep.dataforge.plots.data.TimePlottable;
|
||||||
|
import hep.dataforge.plots.data.TimePlottableGroup;
|
||||||
import hep.dataforge.plots.fx.PlotContainer;
|
import hep.dataforge.plots.fx.PlotContainer;
|
||||||
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
||||||
import hep.dataforge.values.Value;
|
import hep.dataforge.values.Value;
|
||||||
@ -33,6 +32,7 @@ import inr.numass.control.DeviceViewConnection;
|
|||||||
import inr.numass.control.msp.MspDevice;
|
import inr.numass.control.msp.MspDevice;
|
||||||
import inr.numass.control.msp.MspListener;
|
import inr.numass.control.msp.MspListener;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.binding.BooleanBinding;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
@ -72,7 +72,7 @@ public class MspViewController extends DeviceViewConnection<MspDevice> implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PlottableGroup<TimePlottable> plottables = new PlottableGroup<>();
|
private final TimePlottableGroup plottables = new TimePlottableGroup();
|
||||||
// private Configuration viewConfig;
|
// private Configuration viewConfig;
|
||||||
private JFreeChartFrame plot;
|
private JFreeChartFrame plot;
|
||||||
private LogFragment logArea;
|
private LogFragment logArea;
|
||||||
@ -98,7 +98,7 @@ public class MspViewController extends DeviceViewConnection<MspDevice> implement
|
|||||||
@FXML
|
@FXML
|
||||||
private Circle fillamentIndicator;
|
private Circle fillamentIndicator;
|
||||||
@FXML
|
@FXML
|
||||||
private ToggleButton plotButton;
|
private ToggleButton measureButton;
|
||||||
@FXML
|
@FXML
|
||||||
private BorderPane plotPane;
|
private BorderPane plotPane;
|
||||||
@FXML
|
@FXML
|
||||||
@ -143,12 +143,16 @@ public class MspViewController extends DeviceViewConnection<MspDevice> implement
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BooleanBinding disabled = connectButton.selectedProperty().not();
|
||||||
|
fillamentButton.disableProperty().bind(disabled);
|
||||||
|
measureButton.disableProperty().bind(disabled);
|
||||||
|
storeButton.disableProperty().bind(disabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Meta getViewConfig() {
|
public Meta getViewConfig() {
|
||||||
return getDevice().meta().getMeta("plot",getDevice().getMeta());
|
return getDevice().meta().getMeta("plotConfig", getDevice().getMeta());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -158,9 +162,7 @@ public class MspViewController extends DeviceViewConnection<MspDevice> implement
|
|||||||
getDevice().setMspListener(this);
|
getDevice().setMspListener(this);
|
||||||
updatePlot();
|
updatePlot();
|
||||||
|
|
||||||
//FIXME
|
bindBooleanToState("connected", connectButton.selectedProperty());
|
||||||
getStateBinding("connected").addListener((observable, oldValue, newValue) -> connectButton.setSelected(newValue.booleanValue()));
|
|
||||||
bindStateTo("connected", connectButton.selectedProperty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void setDeviceConfig(Context context, File cfgFile) {
|
// public void setDeviceConfig(Context context, File cfgFile) {
|
||||||
@ -200,10 +202,11 @@ public class MspViewController extends DeviceViewConnection<MspDevice> implement
|
|||||||
if (config.hasMeta("peakJump.peak")) {
|
if (config.hasMeta("peakJump.peak")) {
|
||||||
for (Meta an : config.getMetaList("peakJump.peak")) {
|
for (Meta an : config.getMetaList("peakJump.peak")) {
|
||||||
String mass = an.getString("mass");
|
String mass = an.getString("mass");
|
||||||
|
|
||||||
if (!this.plottables.has(mass)) {
|
if (!this.plottables.has(mass)) {
|
||||||
TimePlottable newPlottable = new TimePlottable(mass, mass);
|
TimePlottable newPlottable = new TimePlottable(mass, mass);
|
||||||
newPlottable.configure(an);
|
newPlottable.configure(an);
|
||||||
|
newPlottable.setMaxItems(1000);
|
||||||
|
newPlottable.setPrefItems(400);
|
||||||
this.plottables.add(newPlottable);
|
this.plottables.add(newPlottable);
|
||||||
plot.add(newPlottable);
|
plot.add(newPlottable);
|
||||||
} else {
|
} else {
|
||||||
@ -256,7 +259,7 @@ public class MspViewController extends DeviceViewConnection<MspDevice> implement
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void onPlotToggle(ActionEvent event) throws ControlException {
|
private void onPlotToggle(ActionEvent event) throws ControlException {
|
||||||
if (plotButton.isSelected()) {
|
if (measureButton.isSelected()) {
|
||||||
getDevice().startMeasurement("peakJump");
|
getDevice().startMeasurement("peakJump");
|
||||||
} else {
|
} else {
|
||||||
getDevice().stopMeasurement(false);
|
getDevice().stopMeasurement(false);
|
||||||
@ -344,20 +347,6 @@ public class MspViewController extends DeviceViewConnection<MspDevice> implement
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node getFXNode() {
|
public Node getFXNode() {
|
||||||
|
@ -16,8 +16,8 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<config>
|
<config>
|
||||||
<device type="msp" name="msp">
|
|
||||||
<storage path="D:/temp/test" />
|
<storage path="D:/temp/test" />
|
||||||
|
<device type="msp" name="msp">
|
||||||
<connection ip="127.0.0.1" port="10014"/>
|
<connection ip="127.0.0.1" port="10014"/>
|
||||||
<peakJump>
|
<peakJump>
|
||||||
<peak mass="2"/>
|
<peak mass="2"/>
|
||||||
@ -30,13 +30,13 @@ limitations under the License.
|
|||||||
<peak mass="28"/>
|
<peak mass="28"/>
|
||||||
<peak mass="32"/>
|
<peak mass="32"/>
|
||||||
</peakJump>
|
</peakJump>
|
||||||
<plot>
|
<plotConfig>
|
||||||
<peakJump>
|
<peakJump>
|
||||||
<peak mass="2" title="hydrogen" color="black" thickness="6"/>
|
<peak mass="2" title="hydrogen" color="black" thickness="6"/>
|
||||||
<peak mass="6" title="tritium" thickness="4"/>
|
<peak mass="6" title="tritium" thickness="4"/>
|
||||||
<peak mass="18" title="water" />
|
<peak mass="18" title="water" />
|
||||||
<peak mass="32" title="oxygen"/>
|
<peak mass="32" title="oxygen"/>
|
||||||
</peakJump>
|
</peakJump>
|
||||||
</plot>
|
</plotConfig>
|
||||||
</device>
|
</device>
|
||||||
</config>
|
</config>
|
@ -23,7 +23,7 @@ limitations under the License.
|
|||||||
<?import javafx.scene.layout.Pane?>
|
<?import javafx.scene.layout.Pane?>
|
||||||
<?import javafx.scene.shape.Circle?>
|
<?import javafx.scene.shape.Circle?>
|
||||||
<?import org.controlsfx.control.ToggleSwitch?>
|
<?import org.controlsfx.control.ToggleSwitch?>
|
||||||
<BorderPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="400.0" minWidth="600.0" prefHeight="480.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.control.msp.fx.MspViewController">
|
<BorderPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="400.0" minWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.control.msp.fx.MspViewController">
|
||||||
<top>
|
<top>
|
||||||
<ToolBar prefHeight="50.0" prefWidth="200.0">
|
<ToolBar prefHeight="50.0" prefWidth="200.0">
|
||||||
<ToggleButton fx:id="connectButton" mnemonicParsing="false" text="Connect" />
|
<ToggleButton fx:id="connectButton" mnemonicParsing="false" text="Connect" />
|
||||||
@ -35,7 +35,7 @@ limitations under the License.
|
|||||||
</ToggleSwitch>
|
</ToggleSwitch>
|
||||||
<Circle fx:id="fillamentIndicator" fill="GRAY" radius="10.0" stroke="BLACK" strokeType="INSIDE" />
|
<Circle fx:id="fillamentIndicator" fill="GRAY" radius="10.0" stroke="BLACK" strokeType="INSIDE" />
|
||||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||||
<ToggleButton fx:id="plotButton" mnemonicParsing="false" onAction="#onPlotToggle" text="Measure" />
|
<ToggleButton fx:id="measureButton" mnemonicParsing="false" onAction="#onPlotToggle" text="Measure" />
|
||||||
<ToggleButton fx:id="storeButton" mnemonicParsing="false" onAction="#onStoreButtonClick" text="Store" />
|
<ToggleButton fx:id="storeButton" mnemonicParsing="false" onAction="#onStoreButtonClick" text="Store" />
|
||||||
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
<Separator orientation="VERTICAL" prefHeight="20.0" />
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
|
@ -2,13 +2,13 @@ package inr.numass.control;
|
|||||||
|
|
||||||
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.fx.fragments.Fragment;
|
import hep.dataforge.fx.fragments.FXFragment;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by darksnake on 20-Oct-16.
|
* Created by darksnake on 20-Oct-16.
|
||||||
*/
|
*/
|
||||||
public abstract class DeviceFragment<T extends Device> extends Fragment implements DeviceListener {
|
public abstract class DeviceFragment<T extends Device> extends FXFragment implements DeviceListener {
|
||||||
|
|
||||||
private final T device;
|
private final T device;
|
||||||
|
|
||||||
|
@ -5,11 +5,8 @@ import hep.dataforge.control.devices.Device;
|
|||||||
import hep.dataforge.control.devices.DeviceListener;
|
import hep.dataforge.control.devices.DeviceListener;
|
||||||
import hep.dataforge.fx.FXObject;
|
import hep.dataforge.fx.FXObject;
|
||||||
import hep.dataforge.values.Value;
|
import hep.dataforge.values.Value;
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.binding.BooleanBinding;
|
|
||||||
import javafx.beans.binding.ObjectBinding;
|
import javafx.beans.binding.ObjectBinding;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -37,19 +34,19 @@ public abstract class DeviceViewConnection<D extends Device> extends DeviceConne
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BooleanBinding getStateBooleanBinding(String state) {
|
|
||||||
ObjectBinding<Value> b = getStateBinding(state);
|
|
||||||
return Bindings.createBooleanBinding(() -> b.get().booleanValue(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind writable state change to given observable value
|
* Bind existing boolean property to writable device state
|
||||||
*
|
*
|
||||||
* @param state
|
* @param state
|
||||||
* @param observable
|
* @param property
|
||||||
*/
|
*/
|
||||||
protected void bindStateTo(String state, ObservableValue<?> observable) {
|
protected void bindBooleanToState(String state, BooleanProperty property) {
|
||||||
observable.addListener((ChangeListener<Object>) (observable1, oldValue, newValue) -> {
|
getStateBinding(state).addListener((observable, oldValue, newValue) -> {
|
||||||
|
if (oldValue != newValue) {
|
||||||
|
property.setValue(newValue.booleanValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
property.addListener((observable, oldValue, newValue) -> {
|
||||||
if (oldValue != newValue) {
|
if (oldValue != newValue) {
|
||||||
getDevice().setState(state, newValue);
|
getDevice().setState(state, newValue);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package inr.numass.control;
|
package inr.numass.control;
|
||||||
|
|
||||||
import hep.dataforge.control.devices.Device;
|
import hep.dataforge.control.devices.Device;
|
||||||
import hep.dataforge.fx.fragments.Fragment;
|
import hep.dataforge.fx.fragments.FXFragment;
|
||||||
import hep.dataforge.fx.fragments.LogFragment;
|
import hep.dataforge.fx.fragments.LogFragment;
|
||||||
import hep.dataforge.utils.MetaFactory;
|
import hep.dataforge.utils.MetaFactory;
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ import hep.dataforge.utils.MetaFactory;
|
|||||||
*/
|
*/
|
||||||
public interface Framework<T extends Device> {
|
public interface Framework<T extends Device> {
|
||||||
LogFragment getLogFragment();
|
LogFragment getLogFragment();
|
||||||
Fragment getPlotFragment();
|
FXFragment getPlotFragment();
|
||||||
DeviceFragment<T> getDeviceFragment();
|
DeviceFragment<T> getDeviceFragment();
|
||||||
MetaFactory<T> getDeviceFactory();
|
MetaFactory<T> getDeviceFactory();
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,10 @@ import hep.dataforge.meta.Meta;
|
|||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by darksnake on 14-May-17.
|
* Created by darksnake on 14-May-17.
|
||||||
@ -31,15 +29,14 @@ public abstract class NumassControlApplication<D extends Device> extends Applica
|
|||||||
rootLogger.setLevel(Level.INFO);
|
rootLogger.setLevel(Level.INFO);
|
||||||
|
|
||||||
DeviceViewConnection<D> controller = buildView();
|
DeviceViewConnection<D> controller = buildView();
|
||||||
BorderPane pane = new BorderPane();
|
|
||||||
pane.setCenter(controller.getFXNode());
|
|
||||||
|
|
||||||
Scene scene = new Scene(pane);
|
Scene scene = new Scene(controller.getPane());
|
||||||
|
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
|
|
||||||
setupDevice(controller);
|
device = setupDevice(controller);
|
||||||
|
setupStage(primaryStage, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,28 +53,30 @@ public abstract class NumassControlApplication<D extends Device> extends Applica
|
|||||||
*/
|
*/
|
||||||
protected abstract DeviceFactory<D> getDeviceFactory();
|
protected abstract DeviceFactory<D> getDeviceFactory();
|
||||||
|
|
||||||
protected abstract void setupStage(Stage stage);
|
protected abstract void setupStage(Stage stage, D device);
|
||||||
|
|
||||||
|
protected abstract boolean acceptDevice(Meta meta);
|
||||||
|
|
||||||
private void setupDevice(DeviceConnection<D> controller) {
|
private D setupDevice(DeviceConnection<D> controller) {
|
||||||
Meta config = NumassControlUtils.getConfig(this)
|
Meta config = NumassControlUtils.getConfig(this)
|
||||||
.orElseGet(() -> NumassControlUtils.readResourceMeta("/config/msp-config.xml"));
|
.orElseGet(() -> NumassControlUtils.readResourceMeta("/config/devices.xml"));
|
||||||
|
|
||||||
Context ctx = NumassControlUtils.setupContext(config);
|
Context ctx = NumassControlUtils.setupContext(config);
|
||||||
Meta mspConfig = NumassControlUtils.findDeviceMeta(config, it -> Objects.equals(it.getString("name"), "msp"))
|
Meta mspConfig = NumassControlUtils.findDeviceMeta(config, this::acceptDevice)
|
||||||
.orElseThrow(() -> new RuntimeException("Msp configuration not found"));
|
.orElseThrow(() -> new RuntimeException("Device configuration not found"));
|
||||||
|
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
try {
|
try {
|
||||||
device = getDeviceFactory().build(ctx, mspConfig);
|
D d = getDeviceFactory().build(ctx, mspConfig);
|
||||||
device.init();
|
d.init();
|
||||||
device.connect(controller, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE);
|
NumassControlUtils.connectStorage(d, config);
|
||||||
NumassControlUtils.connectStorage(device, config);
|
Platform.runLater(() -> {
|
||||||
|
d.connect(controller, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE);
|
||||||
|
});
|
||||||
|
return d;
|
||||||
} catch (ControlException e) {
|
} catch (ControlException e) {
|
||||||
throw new RuntimeException("Failed to build device", e);
|
throw new RuntimeException("Failed to build device", e);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,9 +35,10 @@ public class NumassControlUtils {
|
|||||||
*/
|
*/
|
||||||
public static void connectStorage(Device device, Meta config) {
|
public static void connectStorage(Device device, Meta config) {
|
||||||
//TODO add on reset listener
|
//TODO add on reset listener
|
||||||
if (config.hasMeta("storage")&& device.acceptsRole("storge")) {
|
if (config.hasMeta("storage") && device.acceptsRole(Roles.STORAGE_ROLE)) {
|
||||||
String numassRun = ClientUtils.getRunName(config);
|
String numassRun = ClientUtils.getRunName(config);
|
||||||
config.getMetaList("storage").forEach(node -> {
|
config.getMetaList("storage").forEach(node -> {
|
||||||
|
device.getContext().getLogger().debug("Creating storage for device with meta: {}", node);
|
||||||
Storage storage = StorageFactory.buildStorage(device.getContext(), node);
|
Storage storage = StorageFactory.buildStorage(device.getContext(), node);
|
||||||
if (!numassRun.isEmpty()) {
|
if (!numassRun.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user