From 0bc03b60536ce707724e4c4046a2c07a821d0464 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 31 May 2017 16:53:51 +0300 Subject: [PATCH] Numass control room global update --- numass-control/cryotemp/build.gradle | 4 +- .../inr/numass/control/cryotemp/PKT8App.java | 53 ------- .../control/cryotemp/PKT8DeviceFactory.java | 2 +- .../control/cryotemp/PKT8PlotFragment.java | 35 ---- .../numass/control/cryotemp/PKT8PlotView.java | 144 ----------------- .../inr/numass/control/cryotemp/PKT8View.java | 150 ------------------ .../control/cryotemp/PKT8VirtualPort.java | 9 +- .../inr/numass/control/cryotemp/PKT8App.kt | 48 ++++++ .../control/cryotemp/PKT8ViewConnection.kt | 101 ++++++++---- .../control/magnet/VirtualLambdaPort.java | 5 +- ...ControlFXExtensions.kt => FXExtensions.kt} | 11 +- .../control/NumassControlApplication.kt | 13 +- .../kotlin/inr/numass/viewer/test/JFCTest.kt | 2 +- 13 files changed, 144 insertions(+), 433 deletions(-) delete mode 100644 numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8App.java delete mode 100644 numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotFragment.java delete mode 100644 numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotView.java delete mode 100644 numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8View.java create mode 100644 numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8App.kt rename numass-control/src/main/kotlin/inr/numass/control/{ControlFXExtensions.kt => FXExtensions.kt} (86%) diff --git a/numass-control/cryotemp/build.gradle b/numass-control/cryotemp/build.gradle index 636761f8..010a4e37 100644 --- a/numass-control/cryotemp/build.gradle +++ b/numass-control/cryotemp/build.gradle @@ -16,7 +16,7 @@ dependencies { task debug(dependsOn: classes, type: JavaExec) { main mainClass - args "--config.resource=/config-debug/devices.xml" + args = ["--config.resource=/config-debug/devices.xml"] classpath = sourceSets.main.runtimeClasspath description "Start application in debug mode with default virtual port" group "debug" @@ -24,7 +24,7 @@ task debug(dependsOn: classes, type: JavaExec) { task testRun(dependsOn: classes, type: JavaExec) { main mainClass - args(["--config=D:/temp/test/numass-devices.xml", "--device=thermo-1"]) + args = ["--config=D:/temp/test/numass-devices.xml", "--device=thermo-1"] classpath = sourceSets.main.runtimeClasspath description "Start application using real device" group "debug" diff --git a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8App.java b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8App.java deleted file mode 100644 index b14af643..00000000 --- a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8App.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2015 Alexander Nozik. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package inr.numass.control.cryotemp; - -import hep.dataforge.control.devices.DeviceFactory; -import hep.dataforge.meta.Meta; -import inr.numass.control.DeviceViewConnection; -import inr.numass.control.NumassControlApplication; -import javafx.stage.Stage; - -import java.util.Objects; - -/** - * @author darksnake - */ -public class PKT8App extends NumassControlApplication { - @Override - protected DeviceViewConnection buildView(PKT8Device device) { - return PKT8ViewConnection.build(device.getContext()); - } - - @Override - protected DeviceFactory getDeviceFactory() { - return new PKT8DeviceFactory(); - } - - @Override - 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"); - } - - -} diff --git a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8DeviceFactory.java b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8DeviceFactory.java index f01b63c0..a2448205 100644 --- a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8DeviceFactory.java +++ b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8DeviceFactory.java @@ -22,6 +22,6 @@ public class PKT8DeviceFactory implements DeviceViewFactory { @Override public DeviceViewConnection buildView(Device device) { - return PKT8ViewConnection.build(device.getContext()); + return new PKT8ViewConnection(); } } diff --git a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotFragment.java b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotFragment.java deleted file mode 100644 index 78987bd2..00000000 --- a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotFragment.java +++ /dev/null @@ -1,35 +0,0 @@ -package inr.numass.control.cryotemp; - -import hep.dataforge.control.connections.Roles; -import hep.dataforge.fx.fragments.FXFragment; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; - -import java.io.IOException; - -/** - * Created by darksnake on 07-Oct-16. - */ -public class PKT8PlotFragment extends FXFragment { - private PKT8PlotView plotController; - - public PKT8PlotFragment(PKT8Device device) { - super("PKT8 cryogenic temperature viewer", 600, 400); - - try { - FXMLLoader loader = new FXMLLoader(device.getContext().getClassLoader().getResource("fxml/PKT8Plot.fxml")); - loader.setClassLoader(device.getContext().getClassLoader()); - loader.load(); - plotController = loader.getController(); - device.connect(plotController, Roles.VIEW_ROLE); - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - protected Parent buildRoot() { - return plotController.getPane(); - } -} diff --git a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotView.java b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotView.java deleted file mode 100644 index 37d652e2..00000000 --- a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8PlotView.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2015 Alexander Nozik. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package inr.numass.control.cryotemp; - -import hep.dataforge.control.measurements.Measurement; -import hep.dataforge.control.measurements.MeasurementListener; -import hep.dataforge.meta.Meta; -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; -import java.time.Instant; -import java.util.Collection; -import java.util.ResourceBundle; - -/** - * FXML Controller class - * - * @author darksnake - */ -public class PKT8PlotView extends DeviceViewConnection implements Initializable, MeasurementListener { - - private FXPlotFrame plotFrame; - private TimePlottableGroup plottables; - - @FXML - private BorderPane root; - @FXML - private ToggleButton rawDataButton; - @FXML - private AnchorPane plotArea; - - /** - * 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(device); - } - } - }); - - setupPlotFrame(device.meta().getMetaOrEmpty("plot.frame")); - setupChannels(device); - } - - @Override - public void close() throws Exception { - super.close(); - } - - - /** - * Set o reset plot area - */ - private synchronized void setupPlotFrame(Meta plotFrameMeta) { - plottables = new TimePlottableGroup(); - plottables.setMaxAge(Duration.parse(plotFrameMeta.getString("maxAge", "PT2H"))); - plotArea.getChildren().clear(); - plotFrame = new JFreeChartFrame(plotFrameMeta); - PlotUtils.setXAxis(plotFrame, "timestamp", null, "time"); - PlotContainer container = PlotContainer.anchorTo(plotArea); - container.setPlot(plotFrame); - } - - private void setupChannels(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())) - .forEachOrdered(channel -> { - //plot config from device configuration - TimePlottable plottable = new TimePlottable(channel.getName()); - plottable.configure(channel.meta()); - plottables.add(plottable); - plotFrame.add(plottable); - }); - if (device.meta().hasMeta("plotConfig")) { - plottables.applyConfig(device.meta().getMeta("plotConfig")); - plottables.setMaxItems(1000); - plottables.setPrefItems(400); - } -// getPlottables.applyConfig(plotFrame.getConfig()); - } - - @Override - public synchronized void onMeasurementResult(Measurement measurement, Object result, Instant time) { - PKT8Result res = PKT8Result.class.cast(result); - //PENDING replace by connection? - if (rawDataButton.isSelected()) { - plottables.put(res.getChannel(), res.getRawValue()); - } else { - plottables.put(res.getChannel(), res.getTemperature()); - } - } - - @Override - public void onMeasurementFailed(Measurement measurement, Throwable exception) { - - } - - - @Override - public Node getFXNode() { - return root; - } -} diff --git a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8View.java b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8View.java deleted file mode 100644 index d94cbabb..00000000 --- a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8View.java +++ /dev/null @@ -1,150 +0,0 @@ -package inr.numass.control.cryotemp; - -import hep.dataforge.context.Context; -import hep.dataforge.control.measurements.Measurement; -import hep.dataforge.control.measurements.MeasurementListener; -import hep.dataforge.exceptions.ControlException; -import hep.dataforge.exceptions.MeasurementException; -import hep.dataforge.fx.fragments.FragmentWindow; -import hep.dataforge.fx.fragments.LogFragment; -import inr.numass.control.DeviceViewConnection; -import javafx.application.Platform; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.fxml.Initializable; -import javafx.scene.Node; -import javafx.scene.control.Label; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.ToggleButton; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.layout.BorderPane; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.net.URL; -import java.time.Instant; -import java.util.Comparator; -import java.util.ResourceBundle; - -/** - * Created by darksnake on 07-Oct-16. - */ -public class PKT8View extends DeviceViewConnection implements Initializable, MeasurementListener { - - public static PKT8ViewConnection build(Context context) { - try { - FXMLLoader loader = new FXMLLoader(context.getClassLoader().getResource("fxml/PKT8Indicator.fxml")); - loader.setClassLoader(context.getClassLoader()); - 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 - private ToggleButton storeButton; - @FXML - private ToggleButton consoleButton; - @FXML - private ToggleButton plotButton; - @FXML - private Label lastUpdateLabel; - @FXML - private TableView table; - @FXML - private TableColumn, String> sensorColumn; - @FXML - private TableColumn, Double> resColumn; - @FXML - private TableColumn, String> tempColumn; - - - @Override - public void initialize(URL location, ResourceBundle resources) { - 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.addRootLogHandler(); - new FragmentWindow(logFragment).bindTo(consoleButton); - - - plotFragment = new PKT8PlotFragment(device); - startStopButton.selectedProperty().setValue(getDevice().isMeasuring()); - - new FragmentWindow(plotFragment).bindTo(plotButton); - bindBooleanToState("storing", storeButton.selectedProperty()); - } - - @Override - public void close() throws Exception { - super.close(); - logFragment = null; - plotFragment = null; - } - - @Override - public void onMeasurementResult(Measurement measurement, Object result, Instant time) { - PKT8Result res = PKT8Result.class.cast(result); - Platform.runLater(() -> { - lastUpdateLabel.setText(time.toString()); - table.getItems().removeIf(it -> it.getChannel().equals(res.getChannel())); - table.getItems().add(res); - table.getItems().sort(Comparator.comparing(PKT8Result::getChannel)); - }); - } - - @Override - public void onMeasurementFailed(Measurement measurement, Throwable exception) { - - } - - - private void startMeasurement() throws MeasurementException { - getDevice().startMeasurement(); - } - - private void stopMeasurement() throws MeasurementException { - if (getDevice().isMeasuring()) { - getDevice().stopMeasurement(false); - } - } - - - @FXML - private void onStartStopClick(ActionEvent event) { - if (getDevice() != null) { - try { - if (startStopButton.isSelected()) { - startMeasurement(); - } else { - //in case device started - stopMeasurement(); - } - } catch (ControlException ex) { - getDevice().getLogger().error("Failed to start or stop device", ex); - } - } - } - - @Override - public Node getFXNode() { - return root; - } -} diff --git a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8VirtualPort.java b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8VirtualPort.java index b87045ef..3b089181 100644 --- a/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8VirtualPort.java +++ b/numass-control/cryotemp/src/main/java/inr/numass/control/cryotemp/PKT8VirtualPort.java @@ -27,7 +27,7 @@ public class PKT8VirtualPort extends VirtualPort implements Metoid { } @Override - protected void evaluateRequest(String request) { + protected synchronized void evaluateRequest(String request) { switch (request) { case "s": String[] letters = {"a", "b", "c", "d", "e", "f", "g", "h"}; @@ -48,16 +48,15 @@ public class PKT8VirtualPort extends VirtualPort implements Metoid { () -> { double res = average + generator.nextGaussian() * sigma; //TODO convert double value to formatted string - return letter + "000120000\n"; + return String.format("%s000%d", letter, (int) (res * 100)); }, - Duration.ZERO, Duration.ofMillis(200), letter, "measurement" + Duration.ZERO, Duration.ofMillis(500), letter, "measurement" ); } return; case "p": cancelByTag("measurement"); - this.recievePhrase("stopped\n\r"); - return; + this.receivePhrase("Stopped"); } } diff --git a/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8App.kt b/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8App.kt new file mode 100644 index 00000000..dc20aeb9 --- /dev/null +++ b/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8App.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2015 Alexander Nozik. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package inr.numass.control.cryotemp + +import hep.dataforge.control.connections.Roles +import hep.dataforge.control.devices.DeviceFactory +import hep.dataforge.meta.Meta +import inr.numass.control.DeviceViewConnection +import inr.numass.control.NumassControlApplication +import javafx.stage.Stage + +/** + * @author darksnake + */ +class PKT8App : NumassControlApplication() { + override fun buildView(device: PKT8Device): DeviceViewConnection { + return PKT8ViewConnection().apply { + device.connect(this, Roles.VIEW_ROLE) + } + } + + override val deviceFactory: DeviceFactory = PKT8DeviceFactory() + + override fun setupStage(stage: Stage, device: PKT8Device) { + stage.title = "Numass temperature view " + device.name + stage.minHeight = 400.0 + stage.minWidth = 400.0 + } + + override fun acceptDevice(meta: Meta): Boolean { + return meta.getString("type") == "PKT8" + } + + +} diff --git a/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8ViewConnection.kt b/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8ViewConnection.kt index ba38a3a5..fc12cdc9 100644 --- a/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8ViewConnection.kt +++ b/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8ViewConnection.kt @@ -13,11 +13,13 @@ import hep.dataforge.plots.fx.FXPlotFrame import hep.dataforge.plots.fx.PlotContainer import hep.dataforge.plots.jfreechart.JFreeChartFrame import inr.numass.control.DeviceViewConnection +import inr.numass.control.bindView import javafx.application.Platform +import javafx.beans.binding.ListBinding import javafx.beans.property.SimpleObjectProperty import javafx.collections.FXCollections -import javafx.collections.ListChangeListener -import javafx.collections.transformation.SortedList +import javafx.collections.MapChangeListener +import javafx.collections.ObservableList import javafx.geometry.Orientation import javafx.scene.Node import javafx.scene.Parent @@ -33,10 +35,11 @@ import java.time.Instant * Created by darksnake on 30-May-17. */ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListener { - private val view by lazy { CryoView() } - internal val table = SortedList(FXCollections.observableArrayList()) { r1, r2 -> - r1.channel.compareTo(r2.channel) - } + private val cryoView by lazy{ CryoView()} + private val plotView by lazy { CryoPlotView()} + + internal val table = FXCollections.observableHashMap() + val lastUpdateProperty = SimpleObjectProperty("NEVER") @@ -48,23 +51,21 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen } override fun getFXNode(): Node { - return view.root; + if (!isOpen) { + throw RuntimeException("Not connected!") + } + return cryoView.root; } override fun onMeasurementFailed(measurement: Measurement<*>, exception: Throwable) { - throw exception; + } override fun onMeasurementResult(measurement: Measurement<*>, result: Any, time: Instant) { if (result is PKT8Result) { Platform.runLater { lastUpdateProperty.set(time.toString()) - val item = table.find { it.channel == result.channel }; - if (item == null) { - table.add(result); - } else { - table[table.indexOf(item)] = result - } + table.put(result.channel, result); } } } @@ -74,9 +75,11 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen top { toolbar { togglebutton("Measure") { + isSelected = false bindBooleanToState(Sensor.MEASURING_STATE, selectedProperty()) } togglebutton("Store") { + isSelected = false bindBooleanToState("storing", selectedProperty()) } separator(Orientation.VERTICAL) @@ -85,9 +88,11 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen } separator(Orientation.VERTICAL) togglebutton("Plot") { - FragmentWindow(CryoPlotView().root).bindTo(this) + isSelected = false + bindView(plotView) } togglebutton("Log") { + isSelected = false FragmentWindow(LogFragment().apply { addLogHandler(device.logger) }).bindTo(this) @@ -95,12 +100,24 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen } } center { - tableview(table) { + tableview { + items = object : ListBinding() { + init { + bind(table) + } + + override fun computeValue(): ObservableList { + return FXCollections.observableArrayList(table.values).apply { + sortBy { it.channel } + } + } + + } column("Sensor", PKT8Result::channel); column("Resistance", PKT8Result::rawValue).cellFormat { text = String.format("%.2f", it) } - column("Resistance", PKT8Result::temperature).cellFormat { + column("Temperature", PKT8Result::temperature).cellFormat { text = String.format("%.2f", it) } } @@ -116,7 +133,7 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen } } - inner class CryoPlotView : View() { + inner class CryoPlotView : View("PKT8 temperature plot") { val plotFrameMeta: Meta = device.meta.getMetaOrEmpty("plotConfig") val plotFrame: FXPlotFrame by lazy { @@ -130,27 +147,24 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen val plottables: TimePlottableGroup by lazy { TimePlottableGroup().apply { setMaxAge(Duration.parse(plotFrameMeta.getString("maxAge", "PT2H"))) - table.addListener(ListChangeListener { change -> - while (change.next()) { - change.addedSubList.forEach { - if (rawDataButton.isSelected()) { - plottables.put(it.channel, it.rawValue) - } else { - plottables.put(it.channel, it.temperature) - } - } - } - }) } } override val root: Parent = borderpane { + prefWidth = 800.0 + prefHeight = 600.0 PlotContainer.centerIn(this).plot = plotFrame - bottom { - rawDataButton = togglebutton("Raw data") { - action { - plottables.forEach { - it.clear() + top { + toolbar { + rawDataButton = togglebutton("Raw data") { + isSelected = false + action { + clearPlot() + } + } + button("Reset") { + action { + clearPlot() } } } @@ -158,7 +172,7 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen } init { - val channels = device.chanels + val channels = device.chanels //plot config from device configuration //Do not use view config here, it is applyed separately @@ -176,6 +190,23 @@ class PKT8ViewConnection : DeviceViewConnection(), MeasurementListen plottables.setMaxItems(1000) plottables.setPrefItems(400) } + table.addListener(MapChangeListener { change -> + if (change.wasAdded()) { + change.valueAdded.apply { + if (rawDataButton.isSelected()) { + plottables.put(this.channel, this.rawValue) + } else { + plottables.put(this.channel, this.temperature) + } + } + } + }) + } + + fun clearPlot() { + plottables.forEach { + it.clear() + } } } } diff --git a/numass-control/magnet/src/main/java/inr/numass/control/magnet/VirtualLambdaPort.java b/numass-control/magnet/src/main/java/inr/numass/control/magnet/VirtualLambdaPort.java index f26043d2..ec6e5d10 100644 --- a/numass-control/magnet/src/main/java/inr/numass/control/magnet/VirtualLambdaPort.java +++ b/numass-control/magnet/src/main/java/inr/numass/control/magnet/VirtualLambdaPort.java @@ -18,10 +18,11 @@ package inr.numass.control.magnet; import hep.dataforge.control.ports.VirtualPort; import hep.dataforge.exceptions.PortException; import hep.dataforge.meta.Meta; +import org.slf4j.LoggerFactory; + import java.time.Duration; import java.util.HashMap; import java.util.Map; -import org.slf4j.LoggerFactory; /** * @@ -69,7 +70,7 @@ public class VirtualLambdaPort extends VirtualPort { evaluateRequest(comand.trim(), value.trim()); } catch (RuntimeException ex) { - recievePhrase("FAIL");//TODO какая команда правильная? + receivePhrase("FAIL");//TODO какая команда правильная? LoggerFactory.getLogger(getClass()).error("Request evaluation failure", ex); } diff --git a/numass-control/src/main/kotlin/inr/numass/control/ControlFXExtensions.kt b/numass-control/src/main/kotlin/inr/numass/control/FXExtensions.kt similarity index 86% rename from numass-control/src/main/kotlin/inr/numass/control/ControlFXExtensions.kt rename to numass-control/src/main/kotlin/inr/numass/control/FXExtensions.kt index 9627e4a8..80147e45 100644 --- a/numass-control/src/main/kotlin/inr/numass/control/ControlFXExtensions.kt +++ b/numass-control/src/main/kotlin/inr/numass/control/FXExtensions.kt @@ -1,9 +1,12 @@ package inr.numass.control +import hep.dataforge.fx.fragments.FXFragment +import hep.dataforge.fx.fragments.FragmentWindow import hep.dataforge.values.Value import javafx.beans.value.ObservableValue import javafx.event.EventTarget import javafx.geometry.Orientation +import javafx.scene.control.ToggleButton import javafx.scene.paint.Color import javafx.scene.paint.Paint import javafx.scene.shape.Circle @@ -95,4 +98,10 @@ fun EventTarget.deviceStateIndicator(connection: DeviceViewConnection<*>, state: } separator(Orientation.VERTICAL) } -} \ No newline at end of file +} + +fun ToggleButton.bindView(view: View) { + //TODO use view instead of FXFragment + FragmentWindow(FXFragment.buildFromNode(view.title) { view.root }).bindTo(this) +} + diff --git a/numass-control/src/main/kotlin/inr/numass/control/NumassControlApplication.kt b/numass-control/src/main/kotlin/inr/numass/control/NumassControlApplication.kt index 698bd4e5..ad45e290 100644 --- a/numass-control/src/main/kotlin/inr/numass/control/NumassControlApplication.kt +++ b/numass-control/src/main/kotlin/inr/numass/control/NumassControlApplication.kt @@ -67,7 +67,7 @@ abstract class NumassControlApplication : App() { try { - + @Suppress("UNCHECKED_CAST") val d = deviceFactory.build(ctx, deviceConfig) as D d.init() connectStorage(d, config) @@ -80,9 +80,14 @@ abstract class NumassControlApplication : App() { } override fun stop() { - super.stop() - device.shutdown() - device.context.close() + try { + device.shutdown() + } catch (ex: Exception) { + LoggerFactory.getLogger(javaClass).error("Failed to shutdown application", ex); + } finally { + device.context.close() + super.stop() + } } diff --git a/numass-viewer/src/main/kotlin/inr/numass/viewer/test/JFCTest.kt b/numass-viewer/src/main/kotlin/inr/numass/viewer/test/JFCTest.kt index aab41b2f..898fce71 100644 --- a/numass-viewer/src/main/kotlin/inr/numass/viewer/test/JFCTest.kt +++ b/numass-viewer/src/main/kotlin/inr/numass/viewer/test/JFCTest.kt @@ -31,7 +31,7 @@ class JFCTest : View("My View") { override val root = borderpane { center { container.plot = plot - add(container.root) + add(container.pane) } bottom { add(button)