Cryotemp and server update

This commit is contained in:
Alexander Nozik 2017-05-14 21:51:20 +03:00
parent dcf318b16c
commit ac312b7671
21 changed files with 378 additions and 338 deletions

View File

@ -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);

View File

@ -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();
// }
// }
} }

View File

@ -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,8 +53,8 @@ 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 {

View File

@ -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);
}
} }
} }

View File

@ -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;
}
} }

View File

@ -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;
}
} }

View File

@ -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>

View File

@ -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>

View File

@ -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>
@ -28,4 +29,5 @@
<plotConfig maxItems="5000"> <plotConfig maxItems="5000">
<eachPlot thickness="3"/> <eachPlot thickness="3"/>
</plotConfig> </plotConfig>
</device> </device>
</config>

View File

@ -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>

View File

@ -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>

View File

@ -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) {

View File

@ -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,13 +41,18 @@ 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);
} }
// private Device device; @Override
protected boolean acceptDevice(Meta meta) {
return Objects.equals(meta.getString("name"), "msp");
}
// private Device device;
// //
// //
// /** // /**

View File

@ -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,8 +72,8 @@ 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() {

View File

@ -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>

View File

@ -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" />

View File

@ -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;

View File

@ -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);
} }

View File

@ -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();
} }

View File

@ -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

View File

@ -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 {