Server is now a context plugin

This commit is contained in:
Alexander Nozik 2017-05-13 21:46:12 +03:00
parent 10fc68461f
commit 7749dd31de
21 changed files with 329 additions and 78 deletions

View File

@ -0,0 +1,34 @@
plugins{
id "org.jetbrains.kotlin.jvm" version '1.1.2-2'
id "application"
}
repositories {
mavenCentral()
}
if (!hasProperty('mainClass')) {
ext.mainClass = 'inr.numass.viewer.Viewer'//"inr.numass.viewer.test.TestApp"
}
mainClassName = mainClass
version = "0.1.0"
description = "The control room application for numass slow control"
compileKotlin.kotlinOptions.jvmTarget = "1.8"
dependencies {
compile project(':numass-core')
compile project(':numass-control')
compile 'org.controlsfx:controlsfx:8.40.12'
compile "no.tornado:tornadofx:1.7.4"
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.2-2"
}
apply plugin: 'kotlin'

View File

@ -0,0 +1,33 @@
package inr.numass.control
import hep.dataforge.context.Context
import hep.dataforge.context.Global
import hep.dataforge.control.devices.Device
import hep.dataforge.meta.Meta
import hep.dataforge.storage.api.Storage
import hep.dataforge.storage.commons.StorageFactory
import inr.numass.client.ClientUtils
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import javafx.scene.Node
import tornadofx.*
/**
* Created by darksnake on 12-May-17.
*/
class BoardController(val context: Context = Global.instance(), val meta: Meta) : Controller() {
val devices: ObservableList<Pair<Device, Node?>> = FXCollections.observableArrayList<Pair<Device, Node?>>();
val storage: Storage? by lazy {
if (meta.hasMeta("storage")) {
val numassRun = ClientUtils.getRunName(meta)
var storage = StorageFactory.buildStorage(context, meta.getMeta("storage"));
if(! numassRun.isEmpty()){
storage = storage.buildShelf(numassRun, Meta.empty());
}
return@lazy storage;
} else {
return@lazy null;
}
}
}

View File

@ -0,0 +1,22 @@
package inr.numass.control
import javafx.scene.layout.VBox
import tornadofx.*
/**
* Created by darksnake on 11-May-17.
*/
class BoardView : View("Numass control board") {
private var deviceList: VBox by singleAssign();
private val controller: BoardController by inject();
override val root = borderpane {
center {
deviceList = vbox {
bindChildren(controller.devices) { DeviceInfoView(it).root }
}
}
}
}

View File

@ -0,0 +1,46 @@
package inr.numass.control
import hep.dataforge.control.devices.Device
import hep.dataforge.fx.FXObject
import hep.dataforge.fx.fragments.FragmentWindow
import javafx.beans.property.SimpleObjectProperty
import javafx.scene.Node
import javafx.scene.control.ToggleButton
import tornadofx.*
/**
* A simple device indicator board
* Created by darksnake on 11-May-17.
*/
class DeviceInfoView(val device: Device, node: Node? = null) : Fragment(device.name) {
constructor(pair: Pair<Device, Node?>) : this(pair.first, pair.second);
val deviceNode = SimpleObjectProperty<Node>();
var viewButton: ToggleButton by singleAssign();
override val root = hbox {
label(device.name)
add(Indicator.build(device, Device.INITIALIZED_STATE).fxNode)
viewButton = togglebutton("View") {
disableProperty().bind(deviceNode.isNull);
}
}
init {
FragmentWindow(hep.dataforge.fx.fragments.Fragment.buildFromNode(device.name) { deviceNode.get() })
if (node != null) {
deviceNode.set(node);
} else if (device is FXObject) {
deviceNode.set(device.fxNode)
}
}
fun setDeviceView(node: Node) {
deviceNode.set(node);
}
}

View File

@ -0,0 +1,74 @@
package inr.numass.control
import hep.dataforge.control.connections.DeviceConnection
import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceListener
import hep.dataforge.fx.FXObject
import hep.dataforge.values.Value
import javafx.beans.binding.ObjectBinding
import javafx.scene.Node
import javafx.scene.paint.Color
import javafx.scene.paint.Paint
import javafx.scene.shape.Circle
/**
* Lamp-like indicator
*
* TODO move to general kotlin FX utils
* Created by darksnake on 12-May-17.
*/
open class Indicator(val state: String) : FXObject, DeviceConnection<Device>(), DeviceListener {
private val color = object : ObjectBinding<Paint>() {
override fun computeValue(): Paint {
val value = device.getState(state);
return compute(value);
}
}
private val indicator = Circle();
init {
indicator.fillProperty().bind(color);
}
protected open fun compute(value: Value): Paint {
if (value.booleanValue()) {
return Color.GREEN;
} else {
return Color.GRAY;
}
}
override fun getFXNode(): Node {
return indicator;
}
override fun notifyDeviceStateChanged(device: Device?, name: String?, value: Value?) {
if (name == state) {
color.invalidate();
}
}
companion object {
/**
* Build an indicator
*/
fun build(device: Device, state: String): Indicator {
val indicator = Indicator(state);
device.connect(indicator);
return indicator;
}
/**
* Build an indicator with the custom color builder
*/
fun build(device: Device, state: String, func: (Value)-> Paint): Indicator {
val indicator = object:Indicator(state){
override fun compute(value: Value): Paint {
return func(value);
}
};
device.connect(indicator);
return indicator;
}
}
}

View File

@ -1,7 +1,6 @@
package inr.numass.cryotemp;
import hep.dataforge.control.connections.DeviceConnection;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.MeasurementListener;
@ -9,7 +8,6 @@ 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.values.Value;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
@ -82,22 +80,12 @@ public class PKT8Controller extends DeviceConnection<PKT8Device> implements Init
}
@Override
public void notifyDeviceStateChanged(Device device, String name, Value state) {
}
@Override
public void evaluateDeviceException(Device device, String message, Throwable exception) {
}
public void start() throws MeasurementException {
private void startMeasurement() throws MeasurementException {
getDevice().startMeasurement().addListener(this);
}
public void stop() throws MeasurementException {
private void stopMeasurement() throws MeasurementException {
if (getDevice().isMeasuring()) {
getDevice().getMeasurement().removeListener(this);
getDevice().stopMeasurement(false);
@ -110,10 +98,10 @@ public class PKT8Controller extends DeviceConnection<PKT8Device> implements Init
if (getDevice() != null) {
try {
if (startStopButton.isSelected()) {
start();
startMeasurement();
} else {
//in case device started
stop();
stopMeasurement();
}
} catch (ControlException ex) {
evaluateDeviceException(getDevice(), "Failed to start or stop device", ex);

View File

@ -71,7 +71,8 @@ public class PKT8Device extends PortSensor<PKT8Result> {
public PKT8Device(Context context, Meta meta) {
setContext(context);
setMetaBase(meta);
}
@Override

View File

@ -1,13 +1,9 @@
package inr.numass.cryotemp;
import hep.dataforge.context.Context;
import hep.dataforge.control.connections.Connection;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.devices.DeviceFactory;
import hep.dataforge.meta.Meta;
import java.util.Objects;
/**
* Created by darksnake on 09-May-17.
*/
@ -22,12 +18,4 @@ public class PKT8DeviceFactory implements DeviceFactory<PKT8Device> {
return new PKT8Device(context, meta);
}
@Override
public Connection<PKT8Device> buildConnection(String role, Context context, Meta meta) {
if(Objects.equals(role, Roles.VIEW_ROLE)){
return new PKT8Controller();
} else {
return DeviceFactory.super.buildConnection(role, context, meta);
}
}
}

View File

@ -15,6 +15,7 @@
*/
package inr.numass.control.msp;
import hep.dataforge.context.Context;
import hep.dataforge.control.connections.Roles;
import hep.dataforge.control.connections.StorageConnection;
import hep.dataforge.control.devices.SingleMeasurementDevice;
@ -61,7 +62,15 @@ public class MspDevice extends SingleMeasurementDevice implements PortHandler.Po
private Consumer<MspResponse> responseDelegate;
private Consumer<Throwable> errorDelegate;
// public MspDevice(String name, Context context, Meta config) {
public MspDevice() {
}
public MspDevice(Context context, Meta meta) {
setContext(context);
setMetaBase(meta);
}
// public MspDevice(String name, Context context, Meta config) {
// super(name, context, config);
// }
@Override

View File

@ -15,9 +15,7 @@ public class MspDeviceFactory implements DeviceFactory<MspDevice> {
@Override
public MspDevice build(Context context, Meta config) {
MspDevice device = new MspDevice();
device.setContext(context);
device.configure(config);
MspDevice device = new MspDevice(context,config);
return device;
}
}

View File

@ -348,16 +348,6 @@ public class MspViewController extends DeviceConnection<MspDevice> implements De
}
}
@Override
public void notifyDeviceInitialized(Device device) {
}
@Override
public void notifyDeviceShutdown(Device device) {
}
@Override
public void notifyDeviceStateChanged(Device device, String name, Value state) {

View File

@ -5,6 +5,8 @@
*/
package inr.numass.readvac.app;
import hep.dataforge.context.Context;
import hep.dataforge.context.Global;
import hep.dataforge.control.measurements.Sensor;
import hep.dataforge.exceptions.StorageException;
import hep.dataforge.io.MetaFileReader;
@ -56,26 +58,52 @@ public class ReadVac extends Application {
config = Meta.empty();
}
Sensor<Double> p1 = new MKSVacDevice();
p1.configure(config.getMeta("p1",
() -> new MetaBuilder("p1").setValue("port", "com::/dev/ttyUSB0")));
p1.setName(config.getString("p1.name", "P1"));
Sensor<Double> p2 = new CM32Device();
p2.configure(config.getMeta("p2",
() -> new MetaBuilder("p2").setValue("port", "tcp::192.168.111.32:4002")));
p2.setName(config.getString("p2.name", "P2"));
Sensor<Double> p3 = new CM32Device();
p3.configure(config.getMeta("p3",
() -> new MetaBuilder("p3").setValue("port", "tcp::192.168.111.32:4003")));
p3.setName(config.getString("p3.name", "P3"));
Sensor<Double> px = new VITVacDevice();
px.configure(config.getMeta("px",
() -> new MetaBuilder("px").setValue("port", "tcp::192.168.111.32:4003")));
px.setName(config.getString("px.name", "Px"));
Sensor<Double> baratron = new MKSBaratronDevice();
baratron.configure(config.getMeta("baratron",
() -> new MetaBuilder("baratron").setValue("port", "tcp::192.168.111.33:4004")));
baratron.setName(config.getString("baratron.name", "Baratron"));
Context context = Global.instance();
Meta p1Meta = config.getMeta("p1",
new MetaBuilder("p1")
.setValue("port", "com::/dev/ttyUSB0")
.setValue("name", "P1")
.build()
);
Sensor<Double> p1 = new MKSVacDevice(context, p1Meta);
Meta p2Meta = config.getMeta("p2",
new MetaBuilder("p2")
.setValue("port", "tcp::192.168.111.32:4002")
.setValue("name", "P2")
.build()
);
Sensor<Double> p2 = new CM32Device(context,p2Meta);
Meta p3Meta = config.getMeta("p3",
new MetaBuilder("p3")
.setValue("port", "tcp::192.168.111.32:4003")
.setValue("name", "P3")
.build()
);
Sensor<Double> p3 = new CM32Device(context, p3Meta);
Meta pxMeta = config.getMeta("px",
new MetaBuilder("px")
.setValue("port", "tcp::192.168.111.32:4003")
.setValue("name", "Px")
.build()
);
Sensor<Double> px = new VITVacDevice(context,pxMeta);
Meta baratronMeta = config.getMeta("baratron",
new MetaBuilder("baratron")
.setValue("port", "tcp::192.168.111.33:4004")
.setValue("name", "Baratron")
.build()
);
Sensor<Double> baratron = new MKSBaratronDevice(context,baratronMeta);
VacCollectorDevice collector = new VacCollectorDevice();
collector.configure(config);

View File

@ -5,6 +5,7 @@
*/
package inr.numass.readvac.devices;
import hep.dataforge.context.Context;
import hep.dataforge.control.devices.PortSensor;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.SimpleMeasurement;
@ -13,15 +14,22 @@ import hep.dataforge.control.ports.PortFactory;
import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.description.ValueDef;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.meta.Meta;
/**
*
* @author Alexander Nozik
*/
@ValueDef(name = "port")
@ValueDef(name = "delay")
@ValueDef(name = "timeout")
public class CM32Device extends PortSensor<Double> {
public CM32Device() {
}
public CM32Device(Context context, Meta meta) {
setContext(context);
setMetaBase(meta);
}
@Override
protected PortHandler buildHandler(String portName) throws ControlException {
@ -46,7 +54,7 @@ public class CM32Device extends PortSensor<Double> {
return meta().getString("type", "Leibold CM32");
}
// @Override
// @Override
// protected int timeout() {
// return meta().getInt("timeout", 1000);
// }

View File

@ -5,20 +5,29 @@
*/
package inr.numass.readvac.devices;
import hep.dataforge.context.Context;
import hep.dataforge.control.devices.PortSensor;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.SimpleMeasurement;
import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.description.ValueDef;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.meta.Meta;
/**
*
* @author Alexander Nozik
*/
@ValueDef(name = "channel")
public class MKSBaratronDevice extends PortSensor<Double> {
public MKSBaratronDevice() {
}
public MKSBaratronDevice(Context context, Meta meta) {
setContext(context);
setMetaBase(meta);
}
@Override
protected Measurement<Double> createMeasurement() {

View File

@ -5,12 +5,14 @@
*/
package inr.numass.readvac.devices;
import hep.dataforge.context.Context;
import hep.dataforge.control.devices.PortSensor;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.SimpleMeasurement;
import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.description.ValueDef;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.meta.Meta;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.adapter.JavaBeanBooleanPropertyBuilder;
@ -26,6 +28,14 @@ import java.util.regex.Pattern;
@ValueDef(name = "powerButton", type = "BOOLEAN", def = "true")
public class MKSVacDevice extends PortSensor<Double> {
public MKSVacDevice() {
}
public MKSVacDevice(Context context, Meta meta) {
setContext(context);
setMetaBase(meta);
}
private String talk(String requestContent) throws ControlException {
String answer = getHandler().sendAndWait(String.format("@%s%s;FF", getDeviceAddress(), requestContent), timeout());

View File

@ -5,11 +5,13 @@
*/
package inr.numass.readvac.devices;
import hep.dataforge.context.Context;
import hep.dataforge.control.devices.PortSensor;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.SimpleMeasurement;
import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.meta.Meta;
import java.math.BigDecimal;
import java.math.RoundingMode;
@ -17,11 +19,18 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author Alexander Nozik
*/
public class VITVacDevice extends PortSensor<Double> {
public VITVacDevice() {
}
public VITVacDevice(Context context, Meta meta) {
setContext(context);
setMetaBase(meta);
}
@Override
protected PortHandler buildHandler(String portName) throws ControlException {
PortHandler newHandler = super.buildHandler(portName);

View File

@ -45,7 +45,7 @@ import org.apache.commons.math3.util.FastMath;
*/
@PluginDef(group = "inr.numass", name = "numass",
dependsOn = {"hep.dataforge:math", "hep.dataforge:MINUIT"},
description = "Numass data analysis tools")
info = "Numass data analysis tools")
public class NumassPlugin extends BasicPlugin {
/**

View File

@ -6,11 +6,11 @@
package inr.numass.server;
import freemarker.template.Template;
import hep.dataforge.server.ServletUtils;
import hep.dataforge.storage.api.Loader;
import hep.dataforge.storage.api.StateLoader;
import hep.dataforge.storage.api.Storage;
import hep.dataforge.storage.commons.JSONMetaWriter;
import hep.dataforge.storage.servlet.ServletUtils;
import org.slf4j.LoggerFactory;
import ratpack.handling.Context;
import ratpack.handling.Handler;
@ -19,7 +19,7 @@ import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import static hep.dataforge.storage.servlet.StorageRenderer.renderStorage;
import static hep.dataforge.server.StorageRenderer.renderStorage;
import static inr.numass.server.HandlerUtils.renderStates;
/**

View File

@ -7,11 +7,11 @@ package inr.numass.server;
import freemarker.template.Template;
import hep.dataforge.meta.MetaBuilder;
import hep.dataforge.server.ServletUtils;
import hep.dataforge.server.StorageRatpackHandler;
import hep.dataforge.storage.api.ObjectLoader;
import hep.dataforge.storage.api.PointLoader;
import hep.dataforge.storage.api.Storage;
import hep.dataforge.storage.servlet.ServletUtils;
import hep.dataforge.storage.servlet.StorageRatpackHandler;
import inr.numass.data.NumassData;
import org.slf4j.LoggerFactory;
import ratpack.handling.Context;

View File

@ -3,9 +3,15 @@ plugins{
id "application"
}
repositories {
mavenCentral()
}
if (!hasProperty('mainClass')) {
ext.mainClass = 'inr.numass.viewer.Viewer'//"inr.numass.viewer.test.TestApp"
}
mainClassName = mainClass
version = "0.4.0"
@ -22,10 +28,7 @@ dependencies {
compile 'org.controlsfx:controlsfx:8.40.12'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:'1.1.2-2"
compile "no.tornado:tornadofx:1.7.1"
compile "no.tornado:tornadofx:1.7.4"
}
apply plugin: 'kotlin'
repositories {
mavenCentral()
}

View File

@ -5,6 +5,7 @@ include ":numass-control:cryotemp"
include ":numass-control:magnet"
include ":numass-control:msp"
include ":numass-control:vac"
include ":numass-control:control-room"
//
include ":numass-main"
//