diff --git a/numass-control/control-room/src/main/kotlin/inr/numass/control/DeviceInfoView.kt b/numass-control/control-room/src/main/kotlin/inr/numass/control/DeviceInfoView.kt index 14e3665f..ea3abaf5 100644 --- a/numass-control/control-room/src/main/kotlin/inr/numass/control/DeviceInfoView.kt +++ b/numass-control/control-room/src/main/kotlin/inr/numass/control/DeviceInfoView.kt @@ -2,6 +2,7 @@ package inr.numass.control import hep.dataforge.control.devices.Device import hep.dataforge.fx.FXObject +import hep.dataforge.fx.fragments.FXFragment import hep.dataforge.fx.fragments.FragmentWindow import javafx.beans.property.SimpleObjectProperty import javafx.scene.Node @@ -29,7 +30,7 @@ class DeviceInfoView(val device: Device, node: Node? = null) : Fragment(device.n } init { - FragmentWindow(hep.dataforge.fx.fragments.Fragment.buildFromNode(device.name) { deviceNode.get() }) + FragmentWindow(FXFragment.buildFromNode(device.name) { deviceNode.get() }) if (node != null) { deviceNode.set(node); diff --git a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8App.java b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8App.java index 62d623cd..33b9264f 100644 --- a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8App.java +++ b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8App.java @@ -15,130 +15,137 @@ */ package inr.numass.cryotemp; -import ch.qos.logback.classic.Level; -import hep.dataforge.exceptions.ControlException; -import hep.dataforge.io.MetaFileReader; +import hep.dataforge.control.devices.DeviceFactory; import hep.dataforge.meta.Meta; -import hep.dataforge.meta.MetaUtils; -import hep.dataforge.storage.commons.StorageManager; -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 inr.numass.control.DeviceViewConnection; +import inr.numass.control.NumassControlApplication; import javafx.stage.Stage; -import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.text.ParseException; - -import static hep.dataforge.control.devices.PortSensor.PORT_NAME_KEY; +import java.util.Objects; /** * @author darksnake */ -public class PKT8App extends Application { - - 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); +public class PKT8App extends NumassControlApplication { + @Override + protected DeviceViewConnection buildView() { + return PKT8View.build(); } @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")); - 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; + protected DeviceFactory getDeviceFactory() { + return new PKT8DeviceFactory(); } @Override - public void stop() throws Exception { - super.stop(); - if (device != null) { - device.shutdown(); - } + protected void setupStage(Stage stage, PKT8Device device) { + stage.setTitle("Numass temperature view " + device.getName()); + stage.setMinHeight(400); + 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(); +// } +// } + } diff --git a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8Device.java b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8Device.java index 10017916..f15bf6c9 100644 --- a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8Device.java +++ b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8Device.java @@ -17,8 +17,8 @@ package inr.numass.cryotemp; import hep.dataforge.context.Context; import hep.dataforge.control.collectors.RegularPointCollector; +import hep.dataforge.control.connections.Connection; import hep.dataforge.control.connections.LoaderConnection; -import hep.dataforge.control.connections.PointListenerConnection; import hep.dataforge.control.connections.Roles; import hep.dataforge.control.connections.StorageConnection; 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.tables.DataPoint; import hep.dataforge.tables.PointListener; +import hep.dataforge.tables.TableFormat; import hep.dataforge.tables.TableFormatBuilder; import hep.dataforge.utils.DateTimeUtils; import java.time.Duration; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; /** * 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.POINT_LISTENER_ROLE) -@RoleDef(name = Roles.VIEW_ROLE, objectType = PKT8Controller.class) -@ValueDef(name = "port",def = "virtual", info = "The name of the port for this PKT8") +@RoleDef(name = Roles.VIEW_ROLE, objectType = PKT8View.class) +@ValueDef(name = "port", def = "virtual", info = "The name of the port for this PKT8") public class PKT8Device extends PortSensor { public static final String PKT8_DEVICE_TYPE = "numass:pkt8"; @@ -66,6 +68,11 @@ public class PKT8Device extends PortSensor { private final Map channels = new HashMap<>(); private RegularPointCollector collector; + /** + * Cached values + */ + private TableFormat format; + public PKT8Device() { } @@ -108,8 +115,47 @@ public class PKT8Device extends PortSensor { setSPS(meta().getInt("sps", 0)); 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 @@ -253,50 +299,9 @@ public class PKT8Device extends PortSensor { return getState(ABUF).stringValue(); } - private void setupLoaders() { - - // Building data format - TableFormatBuilder tableFormatBuilder = new TableFormatBuilder() - .addTime("timestamp"); - List names = new ArrayList<>(); - - for (PKT8Channel channel : channels.values()) { - tableFormatBuilder.addNumber(channel.getName()); - names.add(channel.getName()); - } - - // setting up loader for each of storages - List 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); - } +// public void connectPointListener(PointListenerConnection listener) { +// this.connect(listener, Roles.POINT_LISTENER_ROLE); +// } @Override protected Measurement createMeasurement() throws MeasurementException { diff --git a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotFragment.java b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotFragment.java index 45ddbf22..c42f588e 100644 --- a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotFragment.java +++ b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotFragment.java @@ -1,6 +1,7 @@ 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.scene.Parent; @@ -9,13 +10,22 @@ import java.io.IOException; /** * Created by darksnake on 07-Oct-16. */ -public class PKT8PlotFragment extends Fragment { - private final PKT8Device device; - private PKT8PlotController plotController; +public class PKT8PlotFragment extends FXFragment { + private PKT8PlotView plotController; public PKT8PlotFragment(PKT8Device device) { 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) -> { if (device.isMeasuring()) { if (newValue) { @@ -29,13 +39,6 @@ public class PKT8PlotFragment extends Fragment { @Override protected Parent buildRoot() { - FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/PKT8Plot.fxml")); - plotController = new PKT8PlotController(device); - loader.setController(plotController); - try { - return loader.load(); - } catch (IOException e) { - throw new RuntimeException(e); - } + return plotController.getPane(); } } diff --git a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotController.java b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotView.java similarity index 73% rename from numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotController.java rename to numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotView.java index b42b87f8..6fd14efd 100644 --- a/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotController.java +++ b/numass-control/cryotemp/src/main/java/inr/numass/cryotemp/PKT8PlotView.java @@ -18,17 +18,19 @@ package inr.numass.cryotemp; import hep.dataforge.control.measurements.Measurement; import hep.dataforge.control.measurements.MeasurementListener; import hep.dataforge.meta.Meta; -import hep.dataforge.meta.MetaUtils; import hep.dataforge.plots.PlotUtils; import hep.dataforge.plots.data.TimePlottable; import hep.dataforge.plots.data.TimePlottableGroup; import hep.dataforge.plots.fx.FXPlotFrame; import hep.dataforge.plots.fx.PlotContainer; import hep.dataforge.plots.jfreechart.JFreeChartFrame; +import inr.numass.control.DeviceViewConnection; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.Node; import javafx.scene.control.ToggleButton; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.BorderPane; import java.net.URL; import java.time.Duration; @@ -41,53 +43,47 @@ import java.util.ResourceBundle; * * @author darksnake */ -public class PKT8PlotController implements Initializable, MeasurementListener { +public class PKT8PlotView extends DeviceViewConnection implements Initializable, MeasurementListener { - private final PKT8Device device; private FXPlotFrame plotFrame; private TimePlottableGroup plottables; + @FXML + private BorderPane root; @FXML private ToggleButton rawDataButton; @FXML private AnchorPane plotArea; - public PKT8PlotController(PKT8Device device) { - this.device = device; - } - /** * Initializes the controller class. */ @Override public void initialize(URL url, ResourceBundle rb) { + + } + + @Override + public void open(PKT8Device device) throws Exception { + super.open(device); rawDataButton.selectedProperty().addListener(observable -> { if (plotFrame != null) { setupPlotFrame(plotFrame.getConfig()); if (device != null) { - setupChannels(); + setupChannels(device); } } }); - configure(device.getConfig()); - setupChannels(); + setupPlotFrame(device.meta().getMetaOrEmpty("plot.frame")); + setupChannels(device); } - public String getDeviceName() { - return device.getName(); + @Override + 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 @@ -102,23 +98,17 @@ public class PKT8PlotController implements Initializable, MeasurementListener channels = this.device.getChanels(); + private void setupChannels(PKT8Device device) { + Collection channels = device.getChanels(); //plot config from device configuration //Do not use view config here, it is applyed separately channels.stream() .filter(channel -> !plottables.has(channel.getName())) .forEach(channel -> { - //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()); - if (deviceLineMeta.hasMeta("plot")) { - plottable.configure(deviceLineMeta.getMeta("plot")); - } + plottable.configure(channel.meta()); plottables.add(plottable); plotFrame.add(plottable); }); @@ -146,4 +136,8 @@ public class PKT8PlotController implements Initializable, MeasurementListener implements Initializable, DeviceListener, MeasurementListener { +public class PKT8View extends DeviceViewConnection implements Initializable, MeasurementListener { + + 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 PKT8PlotFragment plotFragment; + @FXML + private BorderPane root; @FXML private ToggleButton startStopButton; @FXML @@ -38,7 +54,6 @@ public class PKT8Controller extends DeviceConnection implements Init private ToggleButton plotButton; @FXML private Label lastUpdateLabel; - @FXML private TableView table; @FXML @@ -51,18 +66,30 @@ public class PKT8Controller extends DeviceConnection implements Init @Override 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")); resColumn.setCellValueFactory(new PropertyValueFactory<>("rawString")); 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()); + + new FragmentWindow(logFragment).bindTo(consoleButton); + new FragmentWindow(plotFragment).bindTo(plotButton); + } + + @Override + public void close() throws Exception { + super.close(); + logFragment = null; + plotFragment = null; } @Override @@ -108,4 +135,9 @@ public class PKT8Controller extends DeviceConnection implements Init } } } + + @Override + public Node getFXNode() { + return root; + } } diff --git a/numass-control/cryotemp/src/main/resources/config/defaultConfig.xml b/numass-control/cryotemp/src/main/resources/config/defaultConfig.xml deleted file mode 100644 index 75112b8b..00000000 --- a/numass-control/cryotemp/src/main/resources/config/defaultConfig.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - 120 - - - - - - - - - diff --git a/numass-control/cryotemp/src/main/resources/config/devices.xml b/numass-control/cryotemp/src/main/resources/config/devices.xml new file mode 100644 index 00000000..8a431b9f --- /dev/null +++ b/numass-control/cryotemp/src/main/resources/config/devices.xml @@ -0,0 +1,18 @@ + + + + + + 120 + + + + + + + + + + \ No newline at end of file diff --git a/numass-control/cryotemp/src/main/resources/config/thermo-1.xml b/numass-control/cryotemp/src/main/resources/config/thermo-1.xml index f66e256d..18e1dc1c 100644 --- a/numass-control/cryotemp/src/main/resources/config/thermo-1.xml +++ b/numass-control/cryotemp/src/main/resources/config/thermo-1.xml @@ -1,31 +1,33 @@ - - + - 192.168.111.36:4001 - 1 - "PT60S" + + + 192.168.111.36:4001 + 1 + "PT60S" - - - - - - - - - - + + + + + + + + + + - - - - - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/numass-control/cryotemp/src/main/resources/fxml/PKT8Indicator.fxml b/numass-control/cryotemp/src/main/resources/fxml/PKT8Indicator.fxml index 653f4781..a8c905a6 100644 --- a/numass-control/cryotemp/src/main/resources/fxml/PKT8Indicator.fxml +++ b/numass-control/cryotemp/src/main/resources/fxml/PKT8Indicator.fxml @@ -3,8 +3,8 @@ - +
diff --git a/numass-control/cryotemp/src/main/resources/fxml/PKT8Plot.fxml b/numass-control/cryotemp/src/main/resources/fxml/PKT8Plot.fxml index d0661f2b..74e68099 100644 --- a/numass-control/cryotemp/src/main/resources/fxml/PKT8Plot.fxml +++ b/numass-control/cryotemp/src/main/resources/fxml/PKT8Plot.fxml @@ -20,8 +20,8 @@ limitations under the License. - +
diff --git a/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java b/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java index 7d8340d3..27d307b2 100644 --- a/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java +++ b/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java @@ -428,7 +428,7 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po TableFormat format = builder.build(); - String suffix = DateTimeUtils.now().toString(); + String suffix = DateTimeUtils.fileSuffix(); return LoaderFactory .buildPointLoder(storage, "msp_" + suffix, "", "timestamp", format); } catch (StorageException ex) { diff --git a/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java b/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java index 6dba9373..068829d3 100644 --- a/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java +++ b/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspApp.java @@ -16,12 +16,15 @@ package inr.numass.control.msp.fx; import hep.dataforge.control.devices.DeviceFactory; +import hep.dataforge.meta.Meta; import inr.numass.control.DeviceViewConnection; import inr.numass.control.NumassControlApplication; import inr.numass.control.msp.MspDevice; import inr.numass.control.msp.MspDeviceFactory; import javafx.stage.Stage; +import java.util.Objects; + /** * @author darksnake */ @@ -38,13 +41,18 @@ public class MspApp extends NumassControlApplication { } @Override - protected void setupStage(Stage stage) { + protected void setupStage(Stage stage, MspDevice device) { stage.setTitle("Numass mass-spectrometer view"); stage.setMinHeight(400); stage.setMinWidth(600); } -// private Device device; + @Override + protected boolean acceptDevice(Meta meta) { + return Objects.equals(meta.getString("name"), "msp"); + } + + // private Device device; // // // /** diff --git a/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspViewController.java b/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspViewController.java index cada2b45..ea21168e 100644 --- a/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspViewController.java +++ b/numass-control/msp/src/main/java/inr/numass/control/msp/fx/MspViewController.java @@ -15,7 +15,6 @@ */ package inr.numass.control.msp.fx; -import hep.dataforge.control.devices.Device; import hep.dataforge.control.devices.DeviceListener; import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.PortException; @@ -24,8 +23,8 @@ import hep.dataforge.fx.fragments.LogFragment; import hep.dataforge.meta.ConfigChangeListener; import hep.dataforge.meta.Meta; import hep.dataforge.meta.MetaBuilder; -import hep.dataforge.plots.data.PlottableGroup; import hep.dataforge.plots.data.TimePlottable; +import hep.dataforge.plots.data.TimePlottableGroup; import hep.dataforge.plots.fx.PlotContainer; import hep.dataforge.plots.jfreechart.JFreeChartFrame; 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.MspListener; import javafx.application.Platform; +import javafx.beans.binding.BooleanBinding; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.event.ActionEvent; @@ -72,8 +72,8 @@ public class MspViewController extends DeviceViewConnection implement } } - private final PlottableGroup plottables = new PlottableGroup<>(); -// private Configuration viewConfig; + private final TimePlottableGroup plottables = new TimePlottableGroup(); + // private Configuration viewConfig; private JFreeChartFrame plot; private LogFragment logArea; @@ -98,7 +98,7 @@ public class MspViewController extends DeviceViewConnection implement @FXML private Circle fillamentIndicator; @FXML - private ToggleButton plotButton; + private ToggleButton measureButton; @FXML private BorderPane plotPane; @FXML @@ -143,12 +143,16 @@ public class MspViewController extends DeviceViewConnection implement } }); + BooleanBinding disabled = connectButton.selectedProperty().not(); + fillamentButton.disableProperty().bind(disabled); + measureButton.disableProperty().bind(disabled); + storeButton.disableProperty().bind(disabled); + } - 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 implement getDevice().setMspListener(this); updatePlot(); - //FIXME - getStateBinding("connected").addListener((observable, oldValue, newValue) -> connectButton.setSelected(newValue.booleanValue())); - bindStateTo("connected", connectButton.selectedProperty()); + bindBooleanToState("connected", connectButton.selectedProperty()); } // public void setDeviceConfig(Context context, File cfgFile) { @@ -200,10 +202,11 @@ public class MspViewController extends DeviceViewConnection implement if (config.hasMeta("peakJump.peak")) { for (Meta an : config.getMetaList("peakJump.peak")) { String mass = an.getString("mass"); - if (!this.plottables.has(mass)) { TimePlottable newPlottable = new TimePlottable(mass, mass); newPlottable.configure(an); + newPlottable.setMaxItems(1000); + newPlottable.setPrefItems(400); this.plottables.add(newPlottable); plot.add(newPlottable); } else { @@ -256,7 +259,7 @@ public class MspViewController extends DeviceViewConnection implement @FXML private void onPlotToggle(ActionEvent event) throws ControlException { - if (plotButton.isSelected()) { + if (measureButton.isSelected()) { getDevice().startMeasurement("peakJump"); } else { getDevice().stopMeasurement(false); @@ -344,20 +347,6 @@ public class MspViewController extends DeviceViewConnection 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 public Node getFXNode() { diff --git a/numass-control/msp/src/main/resources/config/msp-config.xml b/numass-control/msp/src/main/resources/config/devices.xml similarity index 93% rename from numass-control/msp/src/main/resources/config/msp-config.xml rename to numass-control/msp/src/main/resources/config/devices.xml index 0c6ed7e5..50ad2faa 100644 --- a/numass-control/msp/src/main/resources/config/msp-config.xml +++ b/numass-control/msp/src/main/resources/config/devices.xml @@ -16,8 +16,8 @@ limitations under the License. --> + - @@ -30,13 +30,13 @@ limitations under the License. - + - + \ No newline at end of file diff --git a/numass-control/msp/src/main/resources/fxml/MspView.fxml b/numass-control/msp/src/main/resources/fxml/MspView.fxml index 5967c0b4..80c2d07b 100644 --- a/numass-control/msp/src/main/resources/fxml/MspView.fxml +++ b/numass-control/msp/src/main/resources/fxml/MspView.fxml @@ -23,7 +23,7 @@ limitations under the License. - + @@ -35,7 +35,7 @@ limitations under the License. - + diff --git a/numass-control/src/main/java/inr/numass/control/DeviceFragment.java b/numass-control/src/main/java/inr/numass/control/DeviceFragment.java index 7a0f14c8..16c7d86e 100644 --- a/numass-control/src/main/java/inr/numass/control/DeviceFragment.java +++ b/numass-control/src/main/java/inr/numass/control/DeviceFragment.java @@ -2,13 +2,13 @@ package inr.numass.control; import hep.dataforge.control.devices.Device; import hep.dataforge.control.devices.DeviceListener; -import hep.dataforge.fx.fragments.Fragment; +import hep.dataforge.fx.fragments.FXFragment; import javafx.scene.Parent; /** * Created by darksnake on 20-Oct-16. */ -public abstract class DeviceFragment extends Fragment implements DeviceListener { +public abstract class DeviceFragment extends FXFragment implements DeviceListener { private final T device; diff --git a/numass-control/src/main/java/inr/numass/control/DeviceViewConnection.java b/numass-control/src/main/java/inr/numass/control/DeviceViewConnection.java index 0abd5ba4..13d9ba28 100644 --- a/numass-control/src/main/java/inr/numass/control/DeviceViewConnection.java +++ b/numass-control/src/main/java/inr/numass/control/DeviceViewConnection.java @@ -5,11 +5,8 @@ import hep.dataforge.control.devices.Device; import hep.dataforge.control.devices.DeviceListener; import hep.dataforge.fx.FXObject; import hep.dataforge.values.Value; -import javafx.beans.binding.Bindings; -import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.ObjectBinding; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; +import javafx.beans.property.BooleanProperty; import java.util.HashMap; import java.util.Map; @@ -37,19 +34,19 @@ public abstract class DeviceViewConnection extends DeviceConne ); } - protected BooleanBinding getStateBooleanBinding(String state) { - ObjectBinding 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 observable + * @param property */ - protected void bindStateTo(String state, ObservableValue observable) { - observable.addListener((ChangeListener) (observable1, oldValue, newValue) -> { + protected void bindBooleanToState(String state, BooleanProperty property) { + getStateBinding(state).addListener((observable, oldValue, newValue) -> { + if (oldValue != newValue) { + property.setValue(newValue.booleanValue()); + } + }); + property.addListener((observable, oldValue, newValue) -> { if (oldValue != newValue) { getDevice().setState(state, newValue); } diff --git a/numass-control/src/main/java/inr/numass/control/Framework.java b/numass-control/src/main/java/inr/numass/control/Framework.java index 43a756dd..d96b8ea4 100644 --- a/numass-control/src/main/java/inr/numass/control/Framework.java +++ b/numass-control/src/main/java/inr/numass/control/Framework.java @@ -1,7 +1,7 @@ package inr.numass.control; 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.utils.MetaFactory; @@ -10,7 +10,7 @@ import hep.dataforge.utils.MetaFactory; */ public interface Framework { LogFragment getLogFragment(); - Fragment getPlotFragment(); + FXFragment getPlotFragment(); DeviceFragment getDeviceFragment(); MetaFactory getDeviceFactory(); } diff --git a/numass-control/src/main/java/inr/numass/control/NumassControlApplication.java b/numass-control/src/main/java/inr/numass/control/NumassControlApplication.java index 49686491..16184d29 100644 --- a/numass-control/src/main/java/inr/numass/control/NumassControlApplication.java +++ b/numass-control/src/main/java/inr/numass/control/NumassControlApplication.java @@ -11,12 +11,10 @@ import hep.dataforge.meta.Meta; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; -import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import org.slf4j.LoggerFactory; import java.util.Locale; -import java.util.Objects; /** * Created by darksnake on 14-May-17. @@ -31,15 +29,14 @@ public abstract class NumassControlApplication extends Applica rootLogger.setLevel(Level.INFO); DeviceViewConnection 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.show(); - setupDevice(controller); + device = setupDevice(controller); + setupStage(primaryStage, device); } /** @@ -56,28 +53,30 @@ public abstract class NumassControlApplication extends Applica */ protected abstract DeviceFactory 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 controller) { + private D setupDevice(DeviceConnection controller) { Meta config = NumassControlUtils.getConfig(this) - .orElseGet(() -> NumassControlUtils.readResourceMeta("/config/msp-config.xml")); + .orElseGet(() -> NumassControlUtils.readResourceMeta("/config/devices.xml")); Context ctx = NumassControlUtils.setupContext(config); - Meta mspConfig = NumassControlUtils.findDeviceMeta(config, it -> Objects.equals(it.getString("name"), "msp")) - .orElseThrow(() -> new RuntimeException("Msp configuration not found")); + Meta mspConfig = NumassControlUtils.findDeviceMeta(config, this::acceptDevice) + .orElseThrow(() -> new RuntimeException("Device configuration not found")); - Platform.runLater(() -> { - try { - device = getDeviceFactory().build(ctx, mspConfig); - device.init(); - device.connect(controller, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE); - NumassControlUtils.connectStorage(device, config); - } catch (ControlException e) { - throw new RuntimeException("Failed to build device", e); - } - }); + try { + D d = getDeviceFactory().build(ctx, mspConfig); + d.init(); + NumassControlUtils.connectStorage(d, config); + Platform.runLater(() -> { + d.connect(controller, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE); + }); + return d; + } catch (ControlException e) { + throw new RuntimeException("Failed to build device", e); + } } @Override diff --git a/numass-control/src/main/java/inr/numass/control/NumassControlUtils.java b/numass-control/src/main/java/inr/numass/control/NumassControlUtils.java index fa37a9dd..f62782c2 100644 --- a/numass-control/src/main/java/inr/numass/control/NumassControlUtils.java +++ b/numass-control/src/main/java/inr/numass/control/NumassControlUtils.java @@ -35,9 +35,10 @@ public class NumassControlUtils { */ public static void connectStorage(Device device, Meta config) { //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); config.getMetaList("storage").forEach(node -> { + device.getContext().getLogger().debug("Creating storage for device with meta: {}", node); Storage storage = StorageFactory.buildStorage(device.getContext(), node); if (!numassRun.isEmpty()) { try {