vac to kotlin finished

This commit is contained in:
Alexander Nozik 2017-06-08 08:19:08 +03:00
parent 5e21fa5a0f
commit a7b5ec1101
28 changed files with 349 additions and 735 deletions

View File

@ -1,4 +1,3 @@
apply plugin: 'application' apply plugin: 'application'
if (!hasProperty('mainClass')) { if (!hasProperty('mainClass')) {
@ -14,18 +13,18 @@ dependencies {
compile project(':numass-control') compile project(':numass-control')
} }
task debug(dependsOn: classes, type: JavaExec) { task testDevice(dependsOn: classes, type: JavaExec) {
main mainClass main mainClass
args = ["--config.resource=/config-debug/devices.xml"] args = ["--config.resource=/config-test/devices.xml"]
classpath = sourceSets.main.runtimeClasspath classpath = sourceSets.main.runtimeClasspath
description "Start application in debug mode with default virtual port" description "Start application in debug mode with default virtual port"
group "debug" group "test"
} }
task testRun(dependsOn: classes, type: JavaExec) { //task testRun(dependsOn: classes, type: JavaExec) {
main mainClass // 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 // classpath = sourceSets.main.runtimeClasspath
description "Start application using real device" // description "Start application using real device"
group "debug" // group "debug"
} //}

View File

@ -16,7 +16,6 @@
package inr.numass.control.cryotemp package inr.numass.control.cryotemp
import hep.dataforge.control.connections.Roles import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.DeviceFactory
import hep.dataforge.meta.Meta 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
@ -32,7 +31,7 @@ class PKT8App : NumassControlApplication<PKT8Device>() {
} }
} }
override val deviceFactory: DeviceFactory = PKT8DeviceFactory() override val deviceFactory = PKT8DeviceFactory()
override fun setupStage(stage: Stage, device: PKT8Device) { override fun setupStage(stage: Stage, device: PKT8Device) {
stage.title = "Numass temperature view " + device.name stage.title = "Numass temperature view " + device.name

View File

@ -9,7 +9,7 @@ import inr.numass.control.DeviceViewFactory
/** /**
* Created by darksnake on 09-May-17. * Created by darksnake on 09-May-17.
*/ */
class PKT8DeviceFactory : DeviceViewFactory { class PKT8DeviceFactory : DeviceViewFactory<PKT8Device> {
override fun getType(): String { override fun getType(): String {
return PKT8Device.PKT8_DEVICE_TYPE return PKT8Device.PKT8_DEVICE_TYPE
} }
@ -18,7 +18,7 @@ class PKT8DeviceFactory : DeviceViewFactory {
return PKT8Device(context, meta) return PKT8Device(context, meta)
} }
override fun buildView(device: Device): DeviceViewConnection<*> { override fun buildView(device: Device): DeviceViewConnection<PKT8Device> {
return PKT8ViewConnection() return PKT8ViewConnection()
} }
} }

View File

@ -21,7 +21,6 @@ import javafx.collections.FXCollections
import javafx.collections.MapChangeListener import javafx.collections.MapChangeListener
import javafx.collections.ObservableList import javafx.collections.ObservableList
import javafx.geometry.Orientation import javafx.geometry.Orientation
import javafx.scene.Node
import javafx.scene.Parent import javafx.scene.Parent
import javafx.scene.control.ToggleButton import javafx.scene.control.ToggleButton
import javafx.scene.layout.Priority import javafx.scene.layout.Priority
@ -34,7 +33,10 @@ import java.time.Instant
* Created by darksnake on 30-May-17. * Created by darksnake on 30-May-17.
*/ */
class PKT8ViewConnection : DeviceViewConnection<PKT8Device>(), MeasurementListener { class PKT8ViewConnection : DeviceViewConnection<PKT8Device>(), MeasurementListener {
private val cryoView by lazy { CryoView() }
override fun buildView(): View {
return CryoView()
}
internal val table = FXCollections.observableHashMap<String, PKT8Result>() internal val table = FXCollections.observableHashMap<String, PKT8Result>()
val lastUpdateProperty = SimpleObjectProperty<String>("NEVER") val lastUpdateProperty = SimpleObjectProperty<String>("NEVER")
@ -46,13 +48,6 @@ class PKT8ViewConnection : DeviceViewConnection<PKT8Device>(), MeasurementListen
} }
} }
override fun getFXNode(): Node {
if (!isOpen) {
throw RuntimeException("Not connected!")
}
return cryoView.root;
}
override fun onMeasurementFailed(measurement: Measurement<*>, exception: Throwable) { override fun onMeasurementFailed(measurement: Measurement<*>, exception: Throwable) {
} }
@ -66,7 +61,7 @@ class PKT8ViewConnection : DeviceViewConnection<PKT8Device>(), MeasurementListen
} }
} }
inner class CryoView() : View() { inner class CryoView : View() {
private var plotButton: ToggleButton by singleAssign() private var plotButton: ToggleButton by singleAssign()
private var logButton: ToggleButton by singleAssign() private var logButton: ToggleButton by singleAssign()

View File

@ -15,7 +15,6 @@
*/ */
package inr.numass.control.msp package inr.numass.control.msp
import hep.dataforge.control.devices.DeviceFactory
import hep.dataforge.meta.Meta 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
@ -30,7 +29,7 @@ class MspApp : NumassControlApplication<MspDevice>() {
return MspViewConnection() return MspViewConnection()
} }
override val deviceFactory: DeviceFactory = MspDeviceFactory() override val deviceFactory = MspDeviceFactory()
override fun setupStage(stage: Stage, device: MspDevice) { override fun setupStage(stage: Stage, device: MspDevice) {

View File

@ -9,7 +9,7 @@ import inr.numass.control.DeviceViewFactory
/** /**
* Created by darksnake on 09-May-17. * Created by darksnake on 09-May-17.
*/ */
class MspDeviceFactory : DeviceViewFactory { class MspDeviceFactory : DeviceViewFactory<MspDevice> {
override fun getType(): String { override fun getType(): String {
return MspDevice.MSP_DEVICE_TYPE return MspDevice.MSP_DEVICE_TYPE
} }
@ -19,7 +19,7 @@ class MspDeviceFactory : DeviceViewFactory {
return device return device
} }
override fun buildView(device: Device): DeviceViewConnection<*> { override fun buildView(device: Device): DeviceViewConnection<MspDevice> {
return MspViewConnection() return MspViewConnection()
} }
} }

View File

@ -41,7 +41,6 @@ import javafx.geometry.Insets
import javafx.geometry.Orientation import javafx.geometry.Orientation
import javafx.scene.Parent import javafx.scene.Parent
import javafx.scene.control.Alert import javafx.scene.control.Alert
import javafx.scene.control.ToggleButton
import javafx.scene.layout.Priority import javafx.scene.layout.Priority
import javafx.scene.layout.VBox import javafx.scene.layout.VBox
import javafx.scene.paint.Paint import javafx.scene.paint.Paint
@ -63,7 +62,7 @@ class MspViewConnection() : DeviceViewConnection<MspDevice>(), DeviceListener, N
} }
override fun buildView(): View { override fun buildView(): View {
return MspView(); return MspView()
} }
override fun pushValue(valueName: String, value: Value) { override fun pushValue(valueName: String, value: Value) {
@ -110,8 +109,6 @@ class MspViewConnection() : DeviceViewConnection<MspDevice>(), DeviceListener, N
} }
} }
private var logButton: ToggleButton by singleAssign()
private val logWindow = FragmentWindow(LogFragment().apply { private val logWindow = FragmentWindow(LogFragment().apply {
addLogHandler(device.logger) addLogHandler(device.logger)
}) })
@ -174,7 +171,7 @@ class MspViewConnection() : DeviceViewConnection<MspDevice>(), DeviceListener, N
} }
separator(Orientation.VERTICAL) separator(Orientation.VERTICAL)
logButton = togglebutton("Log") { togglebutton("Log") {
isSelected = false isSelected = false
logWindow.bindTo(this) logWindow.bindTo(this)
} }
@ -199,7 +196,6 @@ class MspViewConnection() : DeviceViewConnection<MspDevice>(), DeviceListener, N
pl.configureValue("title", title) pl.configureValue("title", title)
} }
} }
} }
} }

View File

@ -24,23 +24,38 @@ import java.util.*
/** /**
* Created by darksnake on 14-May-17. * Created by darksnake on 14-May-17.
*/ */
abstract class DeviceViewConnection<D : Device>() : Component(), Connection<D>, DeviceListener, FXObject { abstract class DeviceViewConnection<D : Device> : Component(), Connection, DeviceListener, FXObject {
private val bindings = HashMap<String, ObjectBinding<Value>>() private val bindings = HashMap<String, ObjectBinding<Value>>()
var device: D by singleAssign() private val deviceProperty = SimpleObjectProperty<D>(this, "device", null)
val device: D
val viewProperty = SimpleObjectProperty<View>(this, "view", null) get() {
var view: View? by viewProperty val res = deviceProperty.get();
if (res == null) {
override fun isOpen(): Boolean { throw RuntimeException("Not connected!");
return this.view != null } else {
return res
}
} }
override fun open(device: D) { private val viewProperty = SimpleObjectProperty<View>(this, "view", null)
val view: View
get() {
if (viewProperty.get() == null) {
viewProperty.set(buildView(device))
}
return viewProperty.get();
}
override fun isOpen(): Boolean {
return this.deviceProperty.get() != null
}
override fun open(obj: Any) {
if (!isOpen) { if (!isOpen) {
this.device = device @Suppress("UNCHECKED_CAST")
this.view = buildView(); deviceProperty.set(obj as D)
} else { } else {
log.warning("Connection already opened") log.warning("Connection already opened")
} }
@ -48,19 +63,17 @@ abstract class DeviceViewConnection<D : Device>() : Component(), Connection<D>,
} }
override fun close() { override fun close() {
view?.close() if (viewProperty.isNotNull.get()) {
this.view = null view.close()
}
deviceProperty.set(null)
} }
override fun getFXNode(): Node { override fun getFXNode(): Node {
if (view == null) { return view.root;
throw RuntimeException("Connection not opened");
} else {
return view!!.root;
}
} }
abstract fun buildView(): View; abstract fun buildView(device: D): View;
/** /**
* Get binding for a given device state * Get binding for a given device state
@ -74,7 +87,7 @@ abstract class DeviceViewConnection<D : Device>() : Component(), Connection<D>,
object : ObjectBinding<Value>() { object : ObjectBinding<Value>() {
override fun computeValue(): Value { override fun computeValue(): Value {
if (isOpen) { if (isOpen) {
return device!!.getState(stateName) return device.getState(stateName)
} else { } else {
return Value.NULL return Value.NULL
} }
@ -103,7 +116,7 @@ abstract class DeviceViewConnection<D : Device>() : Component(), Connection<D>,
property.addListener { observable, oldValue, newValue -> property.addListener { observable, oldValue, newValue ->
if (isOpen && oldValue != newValue) { if (isOpen && oldValue != newValue) {
runAsync { runAsync {
device!!.setState(state, newValue).get().booleanValue(); device.setState(state, newValue).get().booleanValue();
} ui { } ui {
property.set(it) property.set(it)
} }
@ -128,7 +141,7 @@ abstract class DeviceViewConnection<D : Device>() : Component(), Connection<D>,
} }
togglebutton("View") { togglebutton("View") {
isSelected = false isSelected = false
FragmentWindow(FXFragment.buildFromNode(device?.name) { fxNode }).bindTo(this) FragmentWindow(FXFragment.buildFromNode(device.name) { fxNode }).bindTo(this)
} }
} }
} }

View File

@ -3,10 +3,10 @@ package inr.numass.control
import hep.dataforge.control.devices.Device import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceFactory import hep.dataforge.control.devices.DeviceFactory
interface DeviceViewFactory : DeviceFactory { interface DeviceViewFactory<D : Device> : DeviceFactory<D> {
/** /**
* Create but do not connect view connection for the device * Create but do not connect view connection for the device
* @return * @return
*/ */
fun buildView(device: Device): DeviceViewConnection<*> fun buildView(device: Device): DeviceViewConnection<D>
} }

View File

@ -1,16 +1,23 @@
package inr.numass.control package inr.numass.control
import hep.dataforge.kodex.KMetaBuilder
import hep.dataforge.plots.PlotFrame
import hep.dataforge.plots.Plottable
import hep.dataforge.plots.fx.PlotContainer
import hep.dataforge.plots.jfreechart.JFreeChartFrame
import hep.dataforge.values.Value import hep.dataforge.values.Value
import javafx.beans.value.ObservableValue import javafx.beans.value.ObservableValue
import javafx.event.EventTarget import javafx.event.EventTarget
import javafx.geometry.Orientation import javafx.geometry.Orientation
import javafx.scene.Node import javafx.scene.Node
import javafx.scene.layout.BorderPane
import javafx.scene.paint.Color import javafx.scene.paint.Color
import javafx.scene.paint.Paint import javafx.scene.paint.Paint
import javafx.scene.shape.Circle import javafx.scene.shape.Circle
import javafx.scene.shape.StrokeType import javafx.scene.shape.StrokeType
import org.controlsfx.control.ToggleSwitch import org.controlsfx.control.ToggleSwitch
import tornadofx.* import tornadofx.*
import java.util.*
/** /**
@ -128,3 +135,15 @@ fun EventTarget.switch(text: String = "", op: (ToggleSwitch.() -> Unit)? = null)
val switch = ToggleSwitch(text) val switch = ToggleSwitch(text)
return opcr(this, switch, op) return opcr(this, switch, op)
} }
/**
* Add plot
*/
fun BorderPane.plot(plottables: Iterable<Plottable> = Collections.emptyList(), metaTransform: (KMetaBuilder.() -> Unit)? = null): PlotFrame {
val meta = KMetaBuilder("plotFrame");
metaTransform?.invoke(meta)
val plot = JFreeChartFrame(meta)
plot.addAll(plottables)
PlotContainer.centerIn(this).plot = plot
return plot;
}

View File

@ -3,9 +3,9 @@ package inr.numass.control
import ch.qos.logback.classic.Level import ch.qos.logback.classic.Level
import hep.dataforge.control.connections.Roles import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.Device import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceFactory
import hep.dataforge.exceptions.ControlException import hep.dataforge.exceptions.ControlException
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.utils.ContextMetaFactory
import javafx.scene.Scene import javafx.scene.Scene
import javafx.stage.Stage import javafx.stage.Stage
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -31,8 +31,6 @@ abstract class NumassControlApplication<D : Device> : App() {
stage.scene = scene stage.scene = scene
stage.show() stage.show()
setupStage(stage, device) setupStage(stage, device)
setDFStageIcon(stage) setDFStageIcon(stage)
} }
@ -49,7 +47,7 @@ abstract class NumassControlApplication<D : Device> : App() {
* @return * @return
*/ */
protected abstract val deviceFactory: DeviceFactory protected abstract val deviceFactory: ContextMetaFactory<D>
protected abstract fun setupStage(stage: Stage, device: D) protected abstract fun setupStage(stage: Stage, device: D)

View File

@ -3,10 +3,18 @@ apply plugin: 'application'
version = "0.5.0" version = "0.5.0"
if (!hasProperty('mainClass')) { if (!hasProperty('mainClass')) {
ext.mainClass = 'inr.numass.readvac.ReadVac' ext.mainClass = 'inr.numass.control.readvac.ReadVac'
} }
mainClassName = mainClass mainClassName = mainClass
dependencies { dependencies {
compile project(':numass-control') compile project(':numass-control')
} }
task testDevice(dependsOn: classes, type: JavaExec) {
main mainClass
args = ["--config.resource=/config-test/devices.xml"]
classpath = sourceSets.main.runtimeClasspath
description "Start application in debug mode with default virtual port"
group "test"
}

View File

@ -13,16 +13,12 @@ import hep.dataforge.control.measurements.SimpleMeasurement;
import hep.dataforge.control.ports.ComPortHandler; import hep.dataforge.control.ports.ComPortHandler;
import hep.dataforge.control.ports.PortFactory; import hep.dataforge.control.ports.PortFactory;
import hep.dataforge.control.ports.PortHandler; import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.description.ValueDef;
import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.ControlException;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
/** /**
* @author Alexander Nozik * @author Alexander Nozik
*/ */
@ValueDef(name = "port")
@ValueDef(name = "delay")
@ValueDef(name = "timeout")
public class CM32Device extends PortSensor<Double> { public class CM32Device extends PortSensor<Double> {
public CM32Device() { public CM32Device() {
} }
@ -68,7 +64,7 @@ public class CM32Device extends PortSensor<Double> {
this.progressUpdate("No signal"); this.progressUpdate("No signal");
updateState(CONNECTED_STATE, false); updateState(CONNECTED_STATE, false);
return null; return null;
} else if (answer.indexOf("PM1:mbar") < -1) { } else if (!answer.contains("PM1:mbar")) {
this.progressUpdate("Wrong answer: " + answer); this.progressUpdate("Wrong answer: " + answer);
updateState(CONNECTED_STATE, false); updateState(CONNECTED_STATE, false);
return null; return null;

View File

@ -7,7 +7,7 @@ package inr.numass.control.readvac;
import hep.dataforge.context.Context; import hep.dataforge.context.Context;
import hep.dataforge.control.RoleDef; import hep.dataforge.control.RoleDef;
import hep.dataforge.control.collectors.PointCollector; import hep.dataforge.control.collectors.RegularPointCollector;
import hep.dataforge.control.collectors.ValueCollector; import hep.dataforge.control.collectors.ValueCollector;
import hep.dataforge.control.connections.Roles; import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.connections.StorageConnection; import hep.dataforge.control.connections.StorageConnection;
@ -18,7 +18,6 @@ import hep.dataforge.control.measurements.AbstractMeasurement;
import hep.dataforge.control.measurements.Measurement; import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.description.ValueDef; import hep.dataforge.description.ValueDef;
import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.ControlException;
import hep.dataforge.exceptions.MeasurementException;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.storage.api.PointLoader; import hep.dataforge.storage.api.PointLoader;
import hep.dataforge.storage.commons.LoaderFactory; import hep.dataforge.storage.commons.LoaderFactory;
@ -30,6 +29,7 @@ import hep.dataforge.values.Value;
import hep.dataforge.values.ValueType; import hep.dataforge.values.ValueType;
import inr.numass.control.StorageHelper; import inr.numass.control.StorageHelper;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -53,7 +53,6 @@ import static hep.dataforge.control.devices.PortSensor.CONNECTED_STATE;
public class VacCollectorDevice extends Sensor<DataPoint> { public class VacCollectorDevice extends Sensor<DataPoint> {
private Map<String, Sensor<Double>> sensorMap = new LinkedHashMap<>(); private Map<String, Sensor<Double>> sensorMap = new LinkedHashMap<>();
private int delay = 5000;
private StorageHelper helper = new StorageHelper(VacCollectorDevice.this, this::buildLoader); private StorageHelper helper = new StorageHelper(VacCollectorDevice.this, this::buildLoader);
public VacCollectorDevice() { public VacCollectorDevice() {
@ -72,8 +71,7 @@ public class VacCollectorDevice extends Sensor<DataPoint> {
} }
} }
@SuppressWarnings("unchecked") public void setSensors(Sensor<Double>... sensors) {
public void setSensors(Sensor... sensors) {
setSensors(Arrays.asList(sensors)); setSensors(Arrays.asList(sensors));
} }
@ -98,13 +96,13 @@ public class VacCollectorDevice extends Sensor<DataPoint> {
return "Numass vacuum"; return "Numass vacuum";
} }
public void setDelay(int delay) throws MeasurementException { // public void setDelay(int delay) throws MeasurementException {
this.delay = delay; // this.delay = delay;
if (isMeasuring()) { // if (isMeasuring()) {
getMeasurement().stop(false); // getMeasurement().stop(false);
getMeasurement().start(); // getMeasurement().start();
} // }
} // }
@Override @Override
public void shutdown() throws ControlException { public void shutdown() throws ControlException {
@ -130,9 +128,13 @@ public class VacCollectorDevice extends Sensor<DataPoint> {
return sensorMap.values(); return sensorMap.values();
} }
private Duration getAveragingDuration() {
return Duration.parse(meta().getString("averagingDuration", "PT30S"));
}
private class VacuumMeasurement extends AbstractMeasurement<DataPoint> { private class VacuumMeasurement extends AbstractMeasurement<DataPoint> {
private final ValueCollector collector = new PointCollector(this::result, sensorMap.keySet()); private final ValueCollector collector = new RegularPointCollector(getAveragingDuration(), this::result);
private ScheduledExecutorService executor; private ScheduledExecutorService executor;
private ScheduledFuture<?> currentTask; private ScheduledFuture<?> currentTask;
@ -142,11 +144,10 @@ public class VacCollectorDevice extends Sensor<DataPoint> {
} }
@Override @Override
public void start() { public void start() {
executor = Executors executor = Executors.newSingleThreadScheduledExecutor((Runnable r) -> new Thread(r, "VacuumMeasurement thread"));
.newSingleThreadScheduledExecutor((Runnable r) -> new Thread(r, "VacuumMeasurement thread")); int delay = meta().getInt("delay", 5) * 1000;
currentTask = executor.scheduleWithFixedDelay(() -> { currentTask = executor.scheduleWithFixedDelay(() -> {
sensorMap.values().forEach((sensor) -> { sensorMap.values().forEach((sensor) -> {
try { try {

View File

@ -1,52 +0,0 @@
package inr.numass.control.readvac;
import hep.dataforge.context.Context;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.Sensor;
import hep.dataforge.meta.Meta;
import inr.numass.control.DeviceViewConnection;
import inr.numass.control.DeviceViewFactory;
import java.util.List;
import java.util.stream.Collectors;
/**
* A factory for vacuum measurements collector
* Created by darksnake on 16-May-17.
*/
public class VacDeviceFactory implements DeviceViewFactory {
@Override
public String getType() {
return "numass:vac";
}
public Sensor<Double> buildSensor(Context context, Meta sensorConfig) {
switch (sensorConfig.getString("sensorType", "")) {
case "mks":
return new MKSVacDevice(context, sensorConfig);
case "CM32":
return new CM32Device(context, sensorConfig);
case "meradat":
return new MeradatVacDevice(context, sensorConfig);
case "baratron":
return new MKSBaratronDevice(context, sensorConfig);
default:
throw new RuntimeException("Unknown vacuum sensor type");
}
}
@Override
public VacCollectorDevice build(Context context, Meta config) {
List<Sensor<Double>> sensors = config.getMetaList("sensor").stream()
.map(sensorConfig -> buildSensor(context, sensorConfig)).collect(Collectors.toList());
VacCollectorDevice collector = new VacCollectorDevice(context, config);
collector.setSensors(sensors);
return collector;
}
@Override
public DeviceViewConnection buildView(Device device) {
return VacCollectorView.build(device.getContext());
}
}

View File

@ -1,41 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package inr.numass.control.readvac;
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 Alexander Nozik
*/
public class ReadVac extends NumassControlApplication<VacCollectorDevice> {
@Override
protected DeviceViewConnection<VacCollectorDevice> buildView(VacCollectorDevice device) {
return VacCollectorView.build(device.getContext());
}
@Override
protected DeviceFactory getDeviceFactory() {
return new VacDeviceFactory();
}
@Override
protected void setupStage(Stage stage, VacCollectorDevice device) {
stage.setTitle("Numass vacuum measurements");
}
@Override
protected boolean acceptDevice(Meta meta) {
return Objects.equals(meta.getString("type", ""), "numass:vac");
}
}

View File

@ -0,0 +1,34 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package inr.numass.control.readvac
import hep.dataforge.meta.Meta
import hep.dataforge.utils.ContextMetaFactory
import inr.numass.control.DeviceViewConnection
import inr.numass.control.NumassControlApplication
import javafx.stage.Stage
/**
* @author Alexander Nozik
*/
class ReadVac : NumassControlApplication<VacCollectorDevice>() {
override fun buildView(device: VacCollectorDevice): DeviceViewConnection<VacCollectorDevice> {
return VacCollectorViewConnection()
}
override val deviceFactory: ContextMetaFactory<VacCollectorDevice> = VacDeviceFactory()
override fun setupStage(stage: Stage, device: VacCollectorDevice) {
stage.title = "Numass vacuum measurements"
}
override fun acceptDevice(meta: Meta): Boolean {
return meta.getString("type", "") == "numass:vac"
}
}

View File

@ -1,90 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package inr.numass.control.readvac;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.devices.Sensor;
import hep.dataforge.control.virtual.Virtual;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.time.Duration;
/**
*
* @author Alexander Nozik
*/
public class TestVac extends Application {
VacCollectorView controller;
@Override
public void start(Stage stage) {
try {
Sensor<Double> sensor1 = Virtual.randomDoubleSensor("vac1", Duration.ofMillis(200), 1e-5, 2e-6);
Sensor<Double> sensor2 = Virtual.randomDoubleSensor("vac2", Duration.ofMillis(200), 2e-5, 2e-6);
Sensor<Double> sensor3 = Virtual.randomDoubleSensor("vac3", Duration.ofMillis(200), 1e-7, 1e-8);
// Sensor<Double> poweredSensor = new VirtualSensorFactory<Double>(
// "vac4",
// (sensor) -> {
// if (sensor.getState("power").booleanValue()) {
// return 1e-6;
// } else {
// return null;
// }
// })
// .addState("power")
// .setMeta(new MetaBuilder("device")
// .setValue("color", "magenta")
// .setValue("thickness", 3)
// .setValue("powerButton", true))
// .addCommand("setPower", new BiConsumer<Sensor<Double>, Value>() {
// @Override
// public void accept(Sensor<Double> sensor, Value power) {
//
// }
// })
// .build();
VacCollectorDevice collector = new VacCollectorDevice();
collector.setSensors(sensor1, sensor2, sensor3);
collector.init();
// collector.getConfig().putNode(new MetaBuilder("storage").putValue("path", "D:\\temp\\test"));
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/VacCollector.fxml"));
loader.load();
controller = loader.getController();
collector.connect(controller, Roles.VIEW_ROLE);
Scene scene = new Scene(loader.getRoot(), 800, 600);
stage.setTitle("Vacuum measurement test");
stage.setScene(scene);
stage.show();
} catch (Exception ex) {
throw new Error(ex);
}
}
@Override
public void stop() throws Exception {
if (controller != null) {
controller.getDevice().shutdown();
}
super.stop();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

View File

@ -1,277 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package inr.numass.control.readvac;
import hep.dataforge.context.Context;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.Sensor;
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 hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaBuilder;
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 hep.dataforge.tables.DataPoint;
import hep.dataforge.values.Value;
import inr.numass.control.DeviceViewConnection;
import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
import org.controlsfx.control.Notifications;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URL;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
/**
* A view controller for Vac collector
*
* @author <a href="mailto:altavir@gmail.com">Alexander Nozik</a>
*/
public class VacCollectorView extends DeviceViewConnection<VacCollectorDevice> implements Initializable, MeasurementListener {
public static VacCollectorView build(Context context) {
try {
FXMLLoader loader = new FXMLLoader(context.getClassLoader().getResource("fxml/VacCollector.fxml"));
loader.setClassLoader(context.getClassLoader());
loader.load();
return loader.getController();
} catch (IOException e) {
throw new Error(e);
}
}
private final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
private final String[] intervalNames = {"1 sec", "5 sec", "10 sec", "30 sec", "1 min"};
private final int[] intervals = {1000, 5000, 10000, 30000, 60000};
private final List<VacuumeterViewConnection> views = new ArrayList<>();
private TimePlottableGroup plottables;
@FXML
private BorderPane root;
@FXML
private AnchorPane plotHolder;
@FXML
private VBox vacBoxHolder;
@FXML
private Label timeLabel;
@FXML
private ChoiceBox<String> intervalSelector;
@FXML
private ToggleButton startStopButton;
@FXML
private ToggleButton storeButton;
@FXML
private ToggleButton logButton;
@Override
public Node getFXNode() {
return root;
}
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
intervalSelector.setItems(FXCollections.observableArrayList(intervalNames));
intervalSelector.getSelectionModel().select(1);
intervalSelector.getSelectionModel().selectedIndexProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
if (getDevice() != null) {
try {
getDevice().setDelay(intervals[newValue.intValue()]);
} catch (MeasurementException ex) {
evaluateDeviceException(getDevice(), "Failed to restart measurement", null);
}
}
});
LogFragment logFragment = new LogFragment();
new FragmentWindow(logFragment).bindTo(logButton);
logFragment.addRootLogHandler();
}
@Override
public void evaluateDeviceException(Device device, String message, Throwable exception) {
Notifications.create().darkStyle().hideAfter(Duration.seconds(2d)).text(message).showError();
}
@Override
public void open(VacCollectorDevice device) {
super.open(device);
device.getSensors().stream().map((sensor) -> {
VacuumeterViewConnection view;
if (sensor.hasState("power")) {
view = new PoweredVacuumeterViewConnection();
} else {
view = new VacuumeterViewConnection();
}
sensor.connect(view, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE);
return view;
}).forEach(views::add);
setupView();
}
@Override
public void notifyDeviceStateChanged(Device device, String name, Value state) {
}
@Override
public void onMeasurementFailed(Measurement measurement, Throwable exception) {
LoggerFactory.getLogger(getClass()).debug("Exception during measurement: {}", exception.getMessage());
}
@Override
public void onMeasurementResult(Measurement measurement, Object res, Instant time) {
if (plottables != null) {
plottables.put(DataPoint.class.cast(res));
}
Platform.runLater(() -> timeLabel.setText(TIME_FORMAT.format(LocalDateTime.ofInstant(time, ZoneOffset.UTC))));
}
private void setupView() {
vacBoxHolder.getChildren().clear();
plottables = new TimePlottableGroup();
views.forEach((view) -> {
vacBoxHolder.getChildren().add(view.getComponent());
TimePlottable plot = new TimePlottable(view.getTitle(),
view.getDevice().getName());
plot.configure(view.getDevice().meta());
plottables.add(plot);
});
plottables.setValue("thickness", 3);
plottables.setMaxAge(java.time.Duration.ofHours(3));
PlotContainer.anchorTo(plotHolder).setPlot(setupPlot(plottables));
}
private FXPlotFrame setupPlot(TimePlottableGroup plottables) {
Meta plotConfig = new MetaBuilder("plotFrame")
.setNode(new MetaBuilder("yAxis")
.setValue("type", "log")
.setValue("axisTitle", "pressure")
.setValue("axisUnits", "mbar")
)
.setValue("xAxis.type", "time");
JFreeChartFrame frame = new JFreeChartFrame(plotConfig);
frame.addAll(plottables);
return frame;
}
private void startMeasurement() throws ControlException {
getDevice().startMeasurement();
startStopButton.setSelected(true);
}
private void stopMeasurement() {
try {
getDevice().stopMeasurement(false);
for (Sensor sensor : getDevice().getSensors()) {
sensor.stopMeasurement(false);
}
} catch (ControlException ex) {
throw new RuntimeException(ex);
}
}
@FXML
private void onStartStopToggle(ActionEvent event) {
if (startStopButton.isSelected() != getDevice().isMeasuring()) {
//Starting measurement on non-UI thread
new Thread(() -> {
if (startStopButton.isSelected()) {
try {
startMeasurement();
} catch (ControlException ex) {
getDevice().getLogger().error("Failed to start measurement", ex);
startStopButton.setSelected(false);
}
} else {
stopMeasurement();
}
}).start();
}
}
@FXML
private void onStoreToggle(ActionEvent event) {
getDevice().setState("storing", storeButton.isSelected());
// if (storeButton.isSelected()) {
// //creating storage on UI thread
// if (!device.meta().hasMeta("storage")) {
// getLogger().info("Storage not defined. Starting storage selection dialog");
// DirectoryChooser chooser = new DirectoryChooser();
// File storageDir = chooser.showDialog(plotHolder.getScene().getWindow());
// if (storageDir == null) {
// storeButton.setSelected(false);
// throw new RuntimeException("User canceled directory selection");
// }
// device.getConfig().putNode(new MetaBuilder("storage")
// .putValue("path", storageDir.getAbsolutePath()));
// }
// Meta storageConfig = device.meta().getMeta("storage");
// Storage localStorage = StorageManager.buildFrom(device.getContext())
// .buildStorage(storageConfig);
// //Start storage creation on non-UI thread
// new Thread(() -> {
// try {
//
// PointLoader loader;
//
// if (loaderFactory != null) {
// loader = loaderFactory.apply(device, localStorage);
// } else {
// TableFormatBuilder format = new TableFormatBuilder().setType("timestamp", ValueType.TIME);
// device.getSensors().forEach((s) -> {
// format.setType(s.getName(), ValueType.NUMBER);
// });
//
// loader = LoaderFactory.buildPointLoder(localStorage, "vactms",
// device.meta().getString("storage.shelf", ""), "timestamp", format.build());
// }
// storageConnection = new LoaderConnection(loader);
// device.connect(storageConnection, Roles.STORAGE_ROLE);
// } catch (Exception ex) {
// getLogger().error("Failed to start data storing", ex);
// storeButton.setSelected(false);
// }
// }).start();
// } else if (storageConnection != null) {
// device.disconnect(storageConnection);
// }
}
}

View File

@ -0,0 +1,139 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package inr.numass.control.readvac
import hep.dataforge.control.Connection
import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.Sensor
import hep.dataforge.control.measurements.Measurement
import hep.dataforge.control.measurements.MeasurementListener
import hep.dataforge.fx.fragments.FragmentWindow
import hep.dataforge.fx.fragments.LogFragment
import hep.dataforge.plots.data.TimePlottable
import hep.dataforge.plots.data.TimePlottableGroup
import hep.dataforge.values.Value
import inr.numass.control.DeviceViewConnection
import inr.numass.control.deviceStateToggle
import inr.numass.control.plot
import javafx.collections.FXCollections
import javafx.collections.MapChangeListener
import javafx.geometry.Orientation
import javafx.scene.control.ScrollPane
import javafx.scene.layout.Priority
import tornadofx.*
import java.time.Instant
/**
* A view controller for Vac collector
* @author [Alexander Nozik](mailto:altavir@gmail.com)
*/
class VacCollectorViewConnection : DeviceViewConnection<VacCollectorDevice>() {
private val table = FXCollections.observableHashMap<String, Double>()
private val sensorConnection = object : MeasurementListener, Connection{
override fun onMeasurementResult(measurement: Measurement<*>, result: Any, time: Instant?) {
if(result is Double){
table.put(measurement.device.name, result);
}
}
override fun onMeasurementFailed(measurement: Measurement<*>?, exception: Throwable?) {
}
}
private val viewList = FXCollections.observableArrayList<VacViewConnection>();
override fun buildView(device: VacCollectorDevice): View {
return VacCollectorView();
}
override fun open(obj: Any) {
super.open(obj)
device.sensors.forEach { sensor ->
val view = VacViewConnection()
sensor.connect(view, Roles.VIEW_ROLE, Roles.DEVICE_LISTENER_ROLE)
sensor.connect(sensorConnection, Roles.MEASUREMENT_LISTENER_ROLE);
viewList.add(view)
}
}
inner class VacCollectorView : View("Numass vacuum view") {
private val plottables = TimePlottableGroup().apply {
viewList.forEach {
val plot = TimePlottable(it.getTitle(), it.device.name)
plot.configure(it.device.meta())
add(plot)
}
setValue("thickness", 3)
}
private val logWindow = FragmentWindow(LogFragment().apply {
addLogHandler(device.logger)
})
override val root = borderpane {
top {
toolbar {
deviceStateToggle(this@VacCollectorViewConnection, Sensor.MEASURING_STATE, "Measure")
deviceStateToggle(this@VacCollectorViewConnection, "storing", "Store")
pane {
hgrow = Priority.ALWAYS
}
separator(Orientation.VERTICAL)
togglebutton("Log") {
isSelected = false
logWindow.bindTo(this)
}
}
}
plot(plottables) {
"xAxis.type" to "time"
node("yAxis") {
"type" to "log"
"axisTitle" to "presure"
"axisUnits" to "mbar"
}
}
right {
scrollpane {
hbarPolicy = ScrollPane.ScrollBarPolicy.NEVER
vbox {
viewList.forEach {
add(it.fxNode)
separator(Orientation.HORIZONTAL)
}
}
}
// listview(viewList) {
// cellFormat {
// graphic = it.fxNode
// }
// }
}
}
init {
table.addListener { change: MapChangeListener.Change<out String, out Double> ->
if (change.wasAdded()) {
val pl = plottables.get(change.key)
val value = change.valueAdded
if (pl != null) {
if (value > 0) {
pl.put(Value.of(value))
} else {
pl.put(Value.NULL)
}
}
}
}
}
}
}

View File

@ -0,0 +1,46 @@
package inr.numass.control.readvac
import hep.dataforge.context.Context
import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.Sensor
import hep.dataforge.control.virtual.VirtualDevice
import hep.dataforge.meta.Meta
import inr.numass.control.DeviceViewConnection
import inr.numass.control.DeviceViewFactory
import java.util.stream.Collectors
/**
* A factory for vacuum measurements collector
* Created by darksnake on 16-May-17.
*/
class VacDeviceFactory : DeviceViewFactory<VacCollectorDevice> {
override fun getType(): String {
return "numass:vac"
}
fun buildSensor(context: Context, sensorConfig: Meta): Sensor<Double> {
when (sensorConfig.getString("sensorType", "")) {
"mks" -> return MKSVacDevice(context, sensorConfig)
"CM32" -> return CM32Device(context, sensorConfig)
"meradat" -> return MeradatVacDevice(context, sensorConfig)
"baratron" -> return MKSBaratronDevice(context, sensorConfig)
VirtualDevice.VIRTUAL_SENSOR_TYPE -> return VirtualDevice.randomDoubleSensor(context, sensorConfig)
else -> throw RuntimeException("Unknown vacuum sensor type")
}
}
override fun build(context: Context, config: Meta): VacCollectorDevice {
val sensors = config.getMetaList("sensor").stream()
.map { sensorConfig ->
buildSensor(context, sensorConfig)
}.collect(Collectors.toList<Sensor<Double>>())
val collector = VacCollectorDevice(context, config)
collector.setSensors(sensors)
return collector
}
override fun buildView(device: Device): DeviceViewConnection<VacCollectorDevice> {
return VacCollectorViewConnection();
}
}

View File

@ -13,6 +13,7 @@ import hep.dataforge.control.measurements.MeasurementListener
import inr.numass.control.DeviceViewConnection import inr.numass.control.DeviceViewConnection
import inr.numass.control.switch import inr.numass.control.switch
import javafx.application.Platform import javafx.application.Platform
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty import javafx.beans.property.SimpleStringProperty
import javafx.geometry.Insets import javafx.geometry.Insets
import javafx.geometry.Orientation import javafx.geometry.Orientation
@ -30,7 +31,7 @@ import java.time.format.DateTimeFormatter
/** /**
* @author [Alexander Nozik](mailto:altavir@gmail.com) * @author [Alexander Nozik](mailto:altavir@gmail.com)
*/ */
open class VacuumeterViewConnection : DeviceViewConnection<Sensor<Double>>(), MeasurementListener { open class VacViewConnection : DeviceViewConnection<Sensor<Double>>(), MeasurementListener {
val statusProperty = SimpleStringProperty("") val statusProperty = SimpleStringProperty("")
var status: String by statusProperty var status: String by statusProperty
@ -38,8 +39,11 @@ open class VacuumeterViewConnection : DeviceViewConnection<Sensor<Double>>(), Me
val valueProperty = SimpleStringProperty("---") val valueProperty = SimpleStringProperty("---")
var value: String by valueProperty var value: String by valueProperty
val timeProperty = SimpleObjectProperty<Instant>()
var time: Instant by timeProperty
override fun buildView(): View {
override fun buildView(device: Sensor<Double>): View {
return VacView(); return VacView();
} }
@ -64,17 +68,23 @@ open class VacuumeterViewConnection : DeviceViewConnection<Sensor<Double>>(), Me
} }
override fun onMeasurementResult(measurement: Measurement<*>, res: Any, time: Instant) { override fun onMeasurementResult(measurement: Measurement<*>, res: Any, time: Instant) {
val result = Double::class.java.cast(res) val result = Number::class.java.cast(res).toDouble()
val resString = FORMAT.format(result) val resString = FORMAT.format(result)
Platform.runLater { Platform.runLater {
value = resString value = resString
this.time = time
status = "OK: " + TIME_FORMAT.format(LocalDateTime.ofInstant(time, ZoneOffset.UTC)); status = "OK: " + TIME_FORMAT.format(LocalDateTime.ofInstant(time, ZoneOffset.UTC));
} }
} }
inner class VacView : View("Numass vacuumeter ${device.meta().getString("title", device.name)}") { fun getTitle(): String{
return device.meta().getString("title", device.name);
}
inner class VacView : View("Numass vacuumeter ${getTitle()}") {
override val root = borderpane { override val root = borderpane {
minWidth = 90.0
style { style {
} }

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
<storage path="D:/temp/test"/>
<device type="numass:vac">
<sensor name="test1" color="red" sensorType="@test" mean="1e-6" sigma="5e-7"/>
<sensor name="test2" color="green" sensorType="@test" mean="2e-6" sigma="5e-7"/>
<sensor name="test3" color="blue" sensorType="@test" mean="3e-6" sigma="1e-6"/>
</device>
</config>

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.controlsfx.control.ToggleSwitch?>
<?import java.net.URL?>
<AnchorPane styleClass="vacBox" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
<stylesheets>
<URL value="@vacstyles.css"/>
</stylesheets>
<VBox layoutX="50.0" layoutY="6.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<AnchorPane styleClass="namePane">
<Label id="name" fx:id="deviceNameLabel" alignment="CENTER" prefHeight="40.0" text="device Name"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="50.0"
AnchorPane.topAnchor="0.0"/>
<ToggleSwitch fx:id="disableButton" alignment="CENTER" layoutX="130.0" layoutY="10.0"
prefWidth="40.0" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0"
AnchorPane.topAnchor="10.0"/>
</AnchorPane>
<Separator/>
<BorderPane>
<left>
<Label id="pressure" fx:id="valueLabel" alignment="CENTER_RIGHT" minWidth="110.0"
prefHeight="60.0" text="---" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
</Label>
</left>
<right>
<Label id="units" fx:id="unitLabel" prefHeight="60.0" prefWidth="75.0" text="mbar"
BorderPane.alignment="CENTER">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
</Label>
</right>
</BorderPane>
<Separator/>
<Pane minHeight="30.0" prefHeight="30.0" VBox.vgrow="ALWAYS">
<ToggleSwitch fx:id="powerSwitch" layoutX="58.0" layoutY="5.0" text="Power"/>
</Pane>
<Separator/>
<AnchorPane styleClass="statusPane">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
<Label fx:id="status" maxWidth="200.0" text="Initializing" wrapText="true"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"/>
</AnchorPane>
</VBox>
</AnchorPane>

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<?import java.net.URL?>
<BorderPane fx:id="root" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.control.readvac.VacCollectorView">
<stylesheets>
<URL value="@/fxml/vacstyles.css" />
</stylesheets>
<right>
<ScrollPane fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" minWidth="250.0" BorderPane.alignment="CENTER">
<content>
<VBox fx:id="vacBoxHolder" minWidth="200.0" spacing="2.0" />
</content>
</ScrollPane>
</right>
<center>
<VBox alignment="TOP_CENTER" BorderPane.alignment="CENTER">
<ToolBar>
<ToggleButton fx:id="startStopButton" mnemonicParsing="false" onAction="#onStartStopToggle" text="Measure" />
<ToggleButton fx:id="storeButton" mnemonicParsing="false" onAction="#onStoreToggle" text="Store" />
<Separator orientation="VERTICAL" />
<Label text="Interval: " />
<ChoiceBox fx:id="intervalSelector" prefWidth="150.0" />
<Separator orientation="VERTICAL" />
<Pane HBox.hgrow="ALWAYS" />
<Separator orientation="VERTICAL" />
<ToggleButton fx:id="logButton" mnemonicParsing="false" text="Console" />
</ToolBar>
<AnchorPane fx:id="plotHolder" VBox.vgrow="ALWAYS" />
<HBox styleClass="beveled">
<Label alignment="CENTER_RIGHT" text="Last update: ">
<font>
<Font size="24.0" />
</font>
</Label>
<Label fx:id="timeLabel" text="08.02.2016 15:57" HBox.hgrow="ALWAYS">
<font>
<Font size="24.0" />
</font>
</Label>
</HBox>
</VBox>
</center>
</BorderPane>

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.controlsfx.control.ToggleSwitch?>
<?import java.net.URL?>
<BorderPane fx:id="root" styleClass="vacBox" xmlns="http://javafx.com/javafx/8.0.40"
xmlns:fx="http://javafx.com/fxml/1">
<stylesheets>
<URL value="@vacstyles.css"/>
</stylesheets>
<center>
<VBox>
<AnchorPane styleClass="namePane">
<Label id="name" fx:id="deviceNameLabel" alignment="CENTER" prefHeight="40.0" text="device Name"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="50.0"
AnchorPane.topAnchor="0.0"/>
<ToggleSwitch fx:id="disableButton" alignment="CENTER" layoutX="140.0" layoutY="20.0"
prefWidth="40.0" selected="true" AnchorPane.bottomAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0"/>
</AnchorPane>
<Separator/>
<BorderPane VBox.vgrow="ALWAYS">
<left>
<Label id="pressure" fx:id="valueLabel" alignment="CENTER_RIGHT" minWidth="110.0" prefHeight="60.0"
text="---" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
</Label>
</left>
<right>
<Label id="units" fx:id="unitLabel" prefHeight="60.0" prefWidth="75.0" text="mbar"
BorderPane.alignment="CENTER">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
</Label>
</right>
</BorderPane>
<Separator/>
<AnchorPane styleClass="statusPane">
<VBox.margin>
<Insets/>
</VBox.margin>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
<Label fx:id="status" maxWidth="200.0" text="Initializing" wrapText="true"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"/>
</AnchorPane>
</VBox>
</center>
</BorderPane>

View File

@ -1,30 +0,0 @@
/*
* Empty Stylesheet file.
*/
.vacBox {
-fx-border-color: blue;
}
.vacBox #pressure{
-fx-font-size: 24;
-fx-font-weight: bold
}
.vacBox #units{
-fx-font-size: 24;
}
.vacBox #name{
-fx-font-size: 18;
-fx-font-weight: bold
}
.vacBox .namePane{
-fx-background-color: lavender
}
.beveled{
-fx-border-color: white #676767 #676767 white;
-fx-border-style: solid outside line-join bevel;
}