vac to kotlin finished
This commit is contained in:
parent
5e21fa5a0f
commit
a7b5ec1101
@ -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"
|
||||||
}
|
//}
|
@ -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
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
}
|
}
|
@ -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>
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user