Revised port synchronous commands

This commit is contained in:
Alexander Nozik 2017-06-03 21:05:01 +03:00
parent 203c02bf53
commit 9241177d40
13 changed files with 5073 additions and 89 deletions

View File

@ -29,7 +29,6 @@ import hep.dataforge.control.ports.PortHandler;
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.exceptions.MeasurementException;
import hep.dataforge.exceptions.PortException;
import hep.dataforge.exceptions.StorageException; import hep.dataforge.exceptions.StorageException;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.storage.api.PointLoader; import hep.dataforge.storage.api.PointLoader;
@ -59,6 +58,7 @@ import java.util.stream.Collectors;
@StateDef(@ValueDef(name = "storing")) @StateDef(@ValueDef(name = "storing"))
public class PKT8Device extends PortSensor<PKT8Result> { public class PKT8Device extends PortSensor<PKT8Result> {
public static final String PKT8_DEVICE_TYPE = "numass:pkt8"; public static final String PKT8_DEVICE_TYPE = "numass:pkt8";
private static final Duration TIMEOUT = Duration.ofMillis(400);
public static final String PGA = "pga"; public static final String PGA = "pga";
public static final String SPS = "sps"; public static final String SPS = "sps";
@ -119,7 +119,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
//update parameters from meta //update parameters from meta
if (meta().hasValue("pga")) { if (meta().hasValue("pga")) {
getLogger().info("Setting dynamic range to " + meta().getInt("pga")); getLogger().info("Setting dynamic range to " + meta().getInt("pga"));
String response = getHandler().sendAndWait("g" + meta().getInt("pga"), 400).trim(); String response = sendAndWait("g" + meta().getInt("pga"), TIMEOUT).trim();
if (response.contains("=")) { if (response.contains("=")) {
updateState(PGA, Integer.parseInt(response.substring(4))); updateState(PGA, Integer.parseInt(response.substring(4)));
} else { } else {
@ -177,7 +177,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
} else { } else {
handler = super.buildHandler(portName); handler = super.buildHandler(portName);
} }
handler.setDelimeter("\n"); handler.setDelimiter("\n");
return handler; return handler;
} }
@ -190,7 +190,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
getLogger().info("Setting avaraging buffer size to " + buf); getLogger().info("Setting avaraging buffer size to " + buf);
String response; String response;
try { try {
response = getHandler().sendAndWait("b" + buf, 400).trim(); response = sendAndWait("b" + buf, Duration.ofMillis(400)).trim();
} catch (Exception ex) { } catch (Exception ex) {
response = ex.getMessage(); response = ex.getMessage();
} }
@ -279,7 +279,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
getLogger().info("Setting sampling rate to " + spsToStr(sps)); getLogger().info("Setting sampling rate to " + spsToStr(sps));
String response; String response;
try { try {
response = getHandler().sendAndWait("v" + sps, 400).trim(); response = sendAndWait("v" + sps, TIMEOUT).trim();
} catch (Exception ex) { } catch (Exception ex) {
response = ex.getMessage(); response = ex.getMessage();
} }
@ -324,8 +324,8 @@ public class PKT8Device extends PortSensor<PKT8Result> {
public Measurement<PKT8Result> startMeasurement() throws MeasurementException { public Measurement<PKT8Result> startMeasurement() throws MeasurementException {
//clearing PKT queue //clearing PKT queue
try { try {
getHandler().send("p"); send("p");
getHandler().sendAndWait("p", 400); sendAndWait("p", TIMEOUT);
} catch (ControlException e) { } catch (ControlException e) {
getLogger().error("Failed to clear PKT8 port"); getLogger().error("Failed to clear PKT8 port");
// throw new MeasurementException(e); // throw new MeasurementException(e);
@ -357,10 +357,10 @@ public class PKT8Device extends PortSensor<PKT8Result> {
try { try {
getLogger().info("Starting measurement"); getLogger().info("Starting measurement");
handler.holdBy(this); handler.holdBy(this);
handler.send("s"); send("s");
afterStart(); afterStart();
} catch (PortException ex) { } catch (ControlException ex) {
error("Failed to start measurement", ex); portError("Failed to start measurement", ex);
} }
} }
@ -373,7 +373,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
try { try {
getLogger().info("Stopping measurement"); getLogger().info("Stopping measurement");
String response = getHandler().sendAndWait("p", 400).trim(); String response = sendAndWait("p", TIMEOUT).trim();
// Должно быть именно с большой буквы!!! // Должно быть именно с большой буквы!!!
return "Stopped".equals(response) || "stopped".equals(response); return "Stopped".equals(response) || "stopped".equals(response);
} catch (Exception ex) { } catch (Exception ex) {
@ -389,7 +389,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
@Override @Override
public void accept(String message) { public void acceptPortPhrase(String message) {
String trimmed = message.trim(); String trimmed = message.trim();
if (isStarted()) { if (isStarted()) {
@ -414,7 +414,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
} }
@Override @Override
public void error(String errorMessage, Throwable error) { public void portError(String errorMessage, Throwable error) {
super.error(error); super.error(error);
} }
} }

View File

@ -17,11 +17,13 @@ package inr.numass.control.magnet;
import hep.dataforge.control.ports.PortHandler; import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.control.ports.PortTimeoutException; import hep.dataforge.control.ports.PortTimeoutException;
import hep.dataforge.control.ports.SyncPortController;
import hep.dataforge.exceptions.PortException; import hep.dataforge.exceptions.PortException;
import hep.dataforge.utils.DateTimeUtils; import hep.dataforge.utils.DateTimeUtils;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -44,12 +46,15 @@ public class MagnetController implements PortHandler.PortController {
public static double MIN_DOWN_STEP_SIZE = 0.05; public static double MIN_DOWN_STEP_SIZE = 0.05;
public static double MAX_SPEED = 5d; // 5 A per minute public static double MAX_SPEED = 5d; // 5 A per minute
private final String name; private final String name;
private final PortHandler port; private final PortHandler port;
private final SyncPortController controller = new SyncPortController(this);
private final int address; private final int address;
private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
protected MagnetStateListener listener; protected MagnetStateListener listener;
private volatile double current = 0; private volatile double current = 0;
private int timeout = 200; private Duration timeout = Duration.ofMillis(200);
private Future monitorTask; private Future monitorTask;
private Future updateTask; private Future updateTask;
private Instant lastUpdate = null; private Instant lastUpdate = null;
@ -69,9 +74,9 @@ public class MagnetController implements PortHandler.PortController {
public MagnetController(String name, PortHandler port, int address, int timeout) { public MagnetController(String name, PortHandler port, int address, int timeout) {
this.name = name; this.name = name;
this.port = port; this.port = port;
this.port.setDelimeter("\r");//PENDING меняем состояние внешнего объекта? this.port.setDelimiter("\r");//PENDING меняем состояние внешнего объекта?
this.address = address; this.address = address;
this.timeout = timeout; this.timeout = Duration.ofMillis(timeout);
} }
public MagnetController(PortHandler port, int address, int timeout) { public MagnetController(PortHandler port, int address, int timeout) {
@ -105,12 +110,12 @@ public class MagnetController implements PortHandler.PortController {
} }
@Override @Override
public void accept(String message) { public void acceptPortPhrase(String message) {
} }
@Override @Override
public void error(String errorMessage, Throwable error) { public void portError(String errorMessage, Throwable error) {
if (this.listener != null) { if (this.listener != null) {
listener.error(getName(), errorMessage, error); listener.error(getName(), errorMessage, error);
} else { } else {
@ -120,11 +125,13 @@ public class MagnetController implements PortHandler.PortController {
private String talk(String request) throws PortException { private String talk(String request) throws PortException {
try { try {
return port.sendAndWait(request + "\r", timeout).trim(); port.send(controller,request + "\r");
return controller.waitFor(timeout).trim();
} catch (PortTimeoutException tex) { } catch (PortTimeoutException tex) {
//Single retry on timeout //Single retry on timeout
LoggerFactory.getLogger(getClass()).warn("A timeout exception for request '" + request + "'. Making another atempt."); LoggerFactory.getLogger(getClass()).warn("A timeout exception for request '" + request + "'. Making another atempt.");
return port.sendAndWait(request + "\r", timeout).trim(); port.send(controller,request + "\r");
return controller.waitFor(timeout).trim();
} }
} }
@ -170,7 +177,7 @@ public class MagnetController implements PortHandler.PortController {
protected void setCurrent(double current) throws PortException { protected void setCurrent(double current) throws PortException {
if (!setState("PC", current)) { if (!setState("PC", current)) {
error("Can't set the current", null); portError("Can't set the current", null);
} else { } else {
lastUpdate = DateTimeUtils.now(); lastUpdate = DateTimeUtils.now();
} }
@ -194,7 +201,7 @@ public class MagnetController implements PortHandler.PortController {
*/ */
private MagnetStatus getStatus() throws PortException { private MagnetStatus getStatus() throws PortException {
try { try {
port.holdBy(MagnetController.this); port.holdBy(controller);
if (!setADR()) { if (!setADR()) {
return MagnetStatus.off(); return MagnetStatus.off();
@ -217,7 +224,7 @@ public class MagnetController implements PortHandler.PortController {
} }
return monitor; return monitor;
} finally { } finally {
port.unholdBy(MagnetController.this); port.unholdBy(controller);
} }
} }
@ -250,7 +257,7 @@ public class MagnetController implements PortHandler.PortController {
stopUpdateTask(); stopUpdateTask();
Runnable call = () -> { Runnable call = () -> {
try { try {
port.holdBy(MagnetController.this); port.holdBy(controller);
double measuredI = getCurrent(); double measuredI = getCurrent();
this.current = measuredI; this.current = measuredI;
@ -271,10 +278,10 @@ public class MagnetController implements PortHandler.PortController {
} }
} catch (PortException ex) { } catch (PortException ex) {
error("Error in update task", ex); portError("Error in update task", ex);
stopUpdateTask(); stopUpdateTask();
} finally { } finally {
port.unholdBy(MagnetController.this); port.unholdBy(controller);
} }
}; };
@ -286,7 +293,7 @@ public class MagnetController implements PortHandler.PortController {
public void setOutputMode(boolean out) throws PortException { public void setOutputMode(boolean out) throws PortException {
try { try {
port.holdBy(MagnetController.this); port.holdBy(controller);
if (!setADR()) { if (!setADR()) {
throw new RuntimeException(); throw new RuntimeException();
} }
@ -304,7 +311,7 @@ public class MagnetController implements PortHandler.PortController {
listener.outputModeChanged(getName(), out); listener.outputModeChanged(getName(), out);
} }
} finally { } finally {
port.unholdBy(MagnetController.this); port.unholdBy(controller);
} }
} }
@ -378,7 +385,7 @@ public class MagnetController implements PortHandler.PortController {
try { try {
getStatus(); getStatus();
} catch (PortException ex) { } catch (PortException ex) {
error("Port connection exception during status measurement", ex); portError("Port connection exception during status measurement", ex);
stopMonitorTask(); stopMonitorTask();
} }
}; };
@ -393,17 +400,17 @@ public class MagnetController implements PortHandler.PortController {
public String request(String message) { public String request(String message) {
try { try {
port.holdBy(this); port.holdBy(controller);
try { try {
if (!setADR()) { if (!setADR()) {
throw new Error(); throw new Error();
} }
return talk(message); return talk(message);
} finally { } finally {
port.unholdBy(this); port.unholdBy(controller);
} }
} catch (PortException ex) { } catch (PortException ex) {
error("Can not send message to the port", ex); portError("Can not send message to the port", ex);
return null; return null;
} }
} }

View File

@ -18,6 +18,7 @@ package inr.numass.control.magnet;
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Level;
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.control.ports.SyncPortController;
import hep.dataforge.exceptions.PortException; import hep.dataforge.exceptions.PortException;
import hep.dataforge.utils.DateTimeUtils; import hep.dataforge.utils.DateTimeUtils;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -59,7 +60,7 @@ public class Talk {
while (!"exit".equals(nextString)) { while (!"exit".equals(nextString)) {
try { try {
Instant start = DateTimeUtils.now(); Instant start = DateTimeUtils.now();
String answer = handler.sendAndWait(nextString + "\r", 1000); String answer = SyncPortController.sendAndWait(handler, nextString + "\r", Duration.ofSeconds(1));
//String answer = controller.request(nextString); //String answer = controller.request(nextString);
System.out.printf("ANSWER (latency = %s): %s;%n", Duration.between(start, DateTimeUtils.now()), answer.trim()); System.out.printf("ANSWER (latency = %s): %s;%n", Duration.between(start, DateTimeUtils.now()), answer.trim());
} catch (PortException ex) { } catch (PortException ex) {

File diff suppressed because one or more lines are too long

View File

@ -27,6 +27,7 @@ import hep.dataforge.control.devices.Sensor;
import hep.dataforge.control.devices.StateDef; import hep.dataforge.control.devices.StateDef;
import hep.dataforge.control.measurements.AbstractMeasurement; import hep.dataforge.control.measurements.AbstractMeasurement;
import hep.dataforge.control.ports.PortHandler; import hep.dataforge.control.ports.PortHandler;
import hep.dataforge.control.ports.SyncPortController;
import hep.dataforge.control.ports.TcpPortHandler; import hep.dataforge.control.ports.TcpPortHandler;
import hep.dataforge.description.ValueDef; import hep.dataforge.description.ValueDef;
import hep.dataforge.events.EventBuilder; import hep.dataforge.events.EventBuilder;
@ -55,22 +56,18 @@ import java.util.function.Consumer;
*/ */
@RoleDef(name = Roles.STORAGE_ROLE, objectType = StorageConnection.class) @RoleDef(name = Roles.STORAGE_ROLE, objectType = StorageConnection.class)
@RoleDef(name = Roles.VIEW_ROLE) @RoleDef(name = Roles.VIEW_ROLE)
@StateDef( @StateDef(value = @ValueDef(name = PortSensor.CONNECTED_STATE, info = "Connection with the device itself"), writable = true)
value = @ValueDef(name = PortSensor.CONNECTED_STATE, info = "Connection with the device itself"), @StateDef(value = @ValueDef(name = "storing", info = "Define if this device is currently writes to storage"), writable = true)
writable = true @StateDef(value = @ValueDef(name = "filament", info = "The number of filament in use"), writable = true)
)
@StateDef(
value = @ValueDef(name = "storing", info = "Define if this device is currently writes to storage"),
writable = true
)
@StateDef(value = @ValueDef(name = "filamentOn", info = "Mass-spectrometer filament on"), writable = true) @StateDef(value = @ValueDef(name = "filamentOn", info = "Mass-spectrometer filament on"), writable = true)
@StateDef(@ValueDef(name = "filamentStatus", info = "Filament status")) @StateDef(@ValueDef(name = "filamentStatus", info = "Filament status"))
public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortController { public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortController {
public static final String MSP_DEVICE_TYPE = "msp"; public static final String MSP_DEVICE_TYPE = "msp";
private static final int TIMEOUT = 200; private static final Duration TIMEOUT = Duration.ofMillis(200);
private TcpPortHandler handler; private TcpPortHandler handler;
private SyncPortController controller = new SyncPortController(this);
private Consumer<MspResponse> measurementDelegate; private Consumer<MspResponse> measurementDelegate;
public MspDevice() { public MspDevice() {
@ -91,7 +88,7 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
int port = meta().getInt("connection.port", 10014); int port = meta().getInt("connection.port", 10014);
getLogger().info("Connection to MKS mass-spectrometer on {}:{}...", ip, port); getLogger().info("Connection to MKS mass-spectrometer on {}:{}...", ip, port);
handler = new TcpPortHandler(ip, port); handler = new TcpPortHandler(ip, port);
handler.setDelimeter("\r\r"); handler.setDelimiter("\r\r");
} }
@Override @Override
@ -128,6 +125,8 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
switch (stateName) { switch (stateName) {
case "connected": case "connected":
return false; return false;
case "filament":
return 1;
case "filamentOn": case "filamentOn":
return false;//Always return false on first request return false;//Always return false on first request
case "filamentStatus": case "filamentStatus":
@ -150,6 +149,9 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
case PortSensor.CONNECTED_STATE: case PortSensor.CONNECTED_STATE:
setConnected(value.booleanValue()); setConnected(value.booleanValue());
break; break;
case "filament":
selectFilament(value.intValue());
break;
case "filamentOn": case "filamentOn":
setFilamentOn(value.booleanValue()); setFilamentOn(value.booleanValue());
break; break;
@ -169,12 +171,12 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
String sensorName; String sensorName;
if (isConnected() != connected) { if (isConnected() != connected) {
if (connected) { if (connected) {
handler.holdBy(this); getHandler().holdBy(controller);
MspResponse response = sendAndWait("Sensors"); MspResponse response = sendAndWait("Sensors");
if (response.isOK()) { if (response.isOK()) {
sensorName = response.get(2, 1); sensorName = response.get(2, 1);
} else { } else {
error(response.errorDescription(), null); portError(response.errorDescription(), null);
return false; return false;
} }
//PENDING определеить в конфиге номер прибора //PENDING определеить в конфиге номер прибора
@ -184,7 +186,7 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
updateState("selected", true); updateState("selected", true);
// selected = true; // selected = true;
} else { } else {
error(response.errorDescription(), null); portError(response.errorDescription(), null);
return false; return false;
} }
@ -194,14 +196,14 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
// invalidateState("controlled"); // invalidateState("controlled");
updateState("controlled", true); updateState("controlled", true);
} else { } else {
error(response.errorDescription(), null); portError(response.errorDescription(), null);
return false; return false;
} }
// connected = true; // connected = true;
updateState(PortSensor.CONNECTED_STATE, true); updateState(PortSensor.CONNECTED_STATE, true);
return true; return true;
} else { } else {
handler.unholdBy(this); getHandler().unholdBy(controller);
return !sendAndWait("Release").isOK(); return !sendAndWait("Release").isOK();
} }
@ -263,11 +265,9 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
.build() .build()
); );
String response = getHandler().sendAndWait(
request, getHandler().send(controller, request);
TIMEOUT, String response = controller.waitFor(TIMEOUT, (String str) -> str.trim().startsWith(commandName));
(String str) -> str.trim().startsWith(commandName)
);
return new MspResponse(response); return new MspResponse(response);
} }
@ -287,8 +287,13 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
return getState("filamentOn").booleanValue(); return getState("filamentOn").booleanValue();
} }
public void selectFillament(int filament) throws PortException { public void selectFilament(int filament) throws PortException {
sendAndWait("FilamentSelect", filament); MspResponse response = sendAndWait("FilamentSelect", filament);
if (response.isOK()) {
updateState("filament", response.get(1, 1));
} else {
getLogger().error("Failed to set filament with error: {}", response.errorDescription());
}
} }
/** /**
@ -316,7 +321,7 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
} }
@Override @Override
public void accept(String message) { public void acceptPortPhrase(String message) {
dispatchEvent( dispatchEvent(
EventBuilder EventBuilder
.make("msp") .make("msp")
@ -338,7 +343,7 @@ public class MspDevice extends Sensor<DataPoint> implements PortHandler.PortCont
} }
@Override @Override
public void error(String errorMessage, Throwable error) { public void portError(String errorMessage, Throwable error) {
notifyError(errorMessage, error); notifyError(errorMessage, error);
} }

View File

@ -19,7 +19,6 @@ import hep.dataforge.control.NamedValueListener
import hep.dataforge.control.devices.DeviceListener import hep.dataforge.control.devices.DeviceListener
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.Sensor import hep.dataforge.control.devices.Sensor
import hep.dataforge.control.devices.Sensor.MEASURING_STATE
import hep.dataforge.fx.fragments.FragmentWindow import hep.dataforge.fx.fragments.FragmentWindow
import hep.dataforge.fx.fragments.LogFragment import hep.dataforge.fx.fragments.LogFragment
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
@ -33,6 +32,7 @@ import hep.dataforge.plots.jfreechart.JFreeChartFrame
import hep.dataforge.values.Value import hep.dataforge.values.Value
import inr.numass.control.DeviceViewConnection import inr.numass.control.DeviceViewConnection
import inr.numass.control.deviceStateIndicator import inr.numass.control.deviceStateIndicator
import inr.numass.control.deviceStateToggle
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.collections.FXCollections import javafx.collections.FXCollections
import javafx.collections.MapChangeListener import javafx.collections.MapChangeListener
@ -121,10 +121,12 @@ class MspViewConnection : DeviceViewConnection<MspDevice>(), DeviceListener, Nam
addLogHandler(device.logger) addLogHandler(device.logger)
}) })
val filamentProperty = SimpleObjectProperty<Int>().apply { val filamentProperty = SimpleObjectProperty<Int>(this, "filament", 1).apply {
addListener { _, oldValue, newValue -> addListener { _, oldValue, newValue ->
if (newValue != oldValue) { if (newValue != oldValue) {
device.selectFillament(newValue); runAsync {
device.setState("filament", newValue);
}
} }
} }
} }
@ -134,17 +136,13 @@ class MspViewConnection : DeviceViewConnection<MspDevice>(), DeviceListener, Nam
minWidth = 600.0 minWidth = 600.0
top { top {
toolbar { toolbar {
togglebutton("Connect") { deviceStateToggle(this@MspViewConnection,PortSensor.CONNECTED_STATE,"Connect")
isSelected = false
bindBooleanToState(PortSensor.CONNECTED_STATE, selectedProperty())
}
combobox(filamentProperty, listOf(1, 2)) { combobox(filamentProperty, listOf(1, 2)) {
cellFormat { cellFormat {
text = "Filament $it" text = "Filament $it"
} }
selectionModel.selectFirst()
disableProperty() disableProperty()
.bind(getStateBinding(MEASURING_STATE).booleanBinding { it!!.booleanValue() }) .bind(getBooleanStateBinding(PortSensor.CONNECTED_STATE).not())
} }
add(ToggleSwitch().apply { add(ToggleSwitch().apply {
padding = Insets(5.0, 0.0, 0.0, 0.0) padding = Insets(5.0, 0.0, 0.0, 0.0)
@ -152,7 +150,7 @@ class MspViewConnection : DeviceViewConnection<MspDevice>(), DeviceListener, Nam
.bind(getStateBinding(PortSensor.CONNECTED_STATE).booleanBinding { !it!!.booleanValue() }) .bind(getStateBinding(PortSensor.CONNECTED_STATE).booleanBinding { !it!!.booleanValue() })
bindBooleanToState("filamentOn", selectedProperty()) bindBooleanToState("filamentOn", selectedProperty())
}) })
deviceStateIndicator(this@MspViewConnection, "filamentStatus") { deviceStateIndicator(this@MspViewConnection, "filamentStatus", false) {
when (it.stringValue()) { when (it.stringValue()) {
"ON" -> Paint.valueOf("red") "ON" -> Paint.valueOf("red")
"OFF" -> Paint.valueOf("blue") "OFF" -> Paint.valueOf("blue")
@ -161,7 +159,6 @@ class MspViewConnection : DeviceViewConnection<MspDevice>(), DeviceListener, Nam
} }
} }
separator(Orientation.VERTICAL)
togglebutton("Measure") { togglebutton("Measure") {
isSelected = false isSelected = false
@ -190,8 +187,9 @@ class MspViewConnection : DeviceViewConnection<MspDevice>(), DeviceListener, Nam
} }
PlotContainer.centerIn(this).plot = plotFrame PlotContainer.centerIn(this).plot = plotFrame
} }
init{
table.addListener {change: MapChangeListener.Change<out String, out Value> -> init {
table.addListener { change: MapChangeListener.Change<out String, out Value> ->
if (change.wasAdded()) { if (change.wasAdded()) {
val pl = plottables.get(change.key) val pl = plottables.get(change.key)
val value = change.valueAdded val value = change.valueAdded

View File

@ -1,6 +1,6 @@
package inr.numass.control package inr.numass.control
import hep.dataforge.control.connections.DeviceConnection import hep.dataforge.control.Connection
import hep.dataforge.control.devices.Device import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceListener import hep.dataforge.control.devices.DeviceListener
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
@ -9,10 +9,10 @@ import hep.dataforge.fx.FXObject
import hep.dataforge.fx.fragments.FXFragment import hep.dataforge.fx.fragments.FXFragment
import hep.dataforge.fx.fragments.FragmentWindow import hep.dataforge.fx.fragments.FragmentWindow
import hep.dataforge.values.Value import hep.dataforge.values.Value
import javafx.application.Platform import javafx.beans.binding.BooleanBinding
import javafx.beans.binding.ObjectBinding import javafx.beans.binding.ObjectBinding
import javafx.beans.property.BooleanProperty import javafx.beans.property.BooleanProperty
import javafx.beans.value.ObservableValue import javafx.beans.property.SimpleObjectProperty
import javafx.geometry.Pos import javafx.geometry.Pos
import javafx.scene.Parent import javafx.scene.Parent
import javafx.scene.layout.HBox import javafx.scene.layout.HBox
@ -23,9 +23,24 @@ import java.util.*
/** /**
* Created by darksnake on 14-May-17. * Created by darksnake on 14-May-17.
*/ */
abstract class DeviceViewConnection<D : Device> : DeviceConnection<D>(), DeviceListener, FXObject { abstract class DeviceViewConnection<D : Device> : Component(), Connection<D>, DeviceListener, FXObject {
private val bindings = HashMap<String, ObjectBinding<Value>>() private val bindings = HashMap<String, ObjectBinding<Value>>()
val deviceProperty = SimpleObjectProperty<D>()
var device by deviceProperty
override fun isOpen(): Boolean {
return this.device != null
}
override fun open(device: D) {
this.device = device
}
override fun close() {
this.device = null
}
/** /**
* Get binding for a given device state * Get binding for a given device state
@ -47,7 +62,7 @@ abstract class DeviceViewConnection<D : Device> : DeviceConnection<D>(), DeviceL
} }
} }
fun getBooleanStateBinding(state: String): ObservableValue<Boolean> { fun getBooleanStateBinding(state: String): BooleanBinding {
return getStateBinding(state).booleanBinding { it!!.booleanValue() } return getStateBinding(state).booleanBinding { it!!.booleanValue() }
} }
@ -66,8 +81,11 @@ abstract class DeviceViewConnection<D : Device> : DeviceConnection<D>(), DeviceL
} }
property.addListener { observable, oldValue, newValue -> property.addListener { observable, oldValue, newValue ->
if (isOpen && oldValue != newValue) { if (isOpen && oldValue != newValue) {
val result = device.setState(state, newValue).get().booleanValue(); runAsync {
Platform.runLater { property.set(result) } device.setState(state, newValue).get().booleanValue();
} ui {
property.set(it)
}
} }
} }
} }

View File

@ -4,6 +4,7 @@ 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.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
@ -87,9 +88,11 @@ fun Indicator.bind(connection: DeviceViewConnection<*>, state: String, transform
/** /**
* State name + indicator * State name + indicator
*/ */
fun EventTarget.deviceStateIndicator(connection: DeviceViewConnection<*>, state: String, transform: ((Value) -> Paint)? = null) { fun EventTarget.deviceStateIndicator(connection: DeviceViewConnection<*>, state: String, showName: Boolean = true, transform: ((Value) -> Paint)? = null) {
if (connection.device.hasState(state)) { if (connection.device.hasState(state)) {
text("${state.toUpperCase()}: ") if (showName) {
text("${state.toUpperCase()}: ")
}
indicator { indicator {
bind(connection, state, transform); bind(connection, state, transform);
} }
@ -97,3 +100,22 @@ fun EventTarget.deviceStateIndicator(connection: DeviceViewConnection<*>, state:
} }
} }
/**
* A togglebutton + indicator for boolean state
*/
fun Node.deviceStateToggle(connection: DeviceViewConnection<*>, state: String, title: String = state) {
if (connection.device.hasState(state)) {
togglebutton(title) {
isSelected = false
selectedProperty().addListener { observable, oldValue, newValue ->
if(oldValue!= newValue){
connection.device.setState(state,newValue).thenAccept {
isSelected = it.booleanValue()
}
}
}
}
deviceStateIndicator(connection, state, false)
}
}

View File

@ -41,7 +41,7 @@ public class CM32Device extends PortSensor<Double> {
} else { } else {
newHandler = PortFactory.getPort(portName); newHandler = PortFactory.getPort(portName);
} }
newHandler.setDelimeter("T--\r"); newHandler.setDelimiter("T--\r");
return newHandler; return newHandler;
} }
@ -62,7 +62,7 @@ public class CM32Device extends PortSensor<Double> {
@Override @Override
protected synchronized Double doMeasure() throws Exception { protected synchronized Double doMeasure() throws Exception {
String answer = getHandler().sendAndWait(CM32_QUERY, timeout()); String answer = sendAndWait(CM32_QUERY, timeout());
if (answer.isEmpty()) { if (answer.isEmpty()) {
this.progressUpdate("No signal"); this.progressUpdate("No signal");

View File

@ -43,7 +43,7 @@ public class MKSBaratronDevice extends PortSensor<Double> {
@Override @Override
protected PortHandler buildHandler(String portName) throws ControlException { protected PortHandler buildHandler(String portName) throws ControlException {
PortHandler handler = super.buildHandler(portName); PortHandler handler = super.buildHandler(portName);
handler.setDelimeter("\r"); handler.setDelimiter("\r");
return handler; return handler;
} }
@ -60,7 +60,7 @@ public class MKSBaratronDevice extends PortSensor<Double> {
@Override @Override
protected synchronized Double doMeasure() throws Exception { protected synchronized Double doMeasure() throws Exception {
String answer = getHandler().sendAndWait("AV" + getChannel() + "\r", timeout()); String answer = sendAndWait("AV" + getChannel() + "\r", timeout());
if (answer == null || answer.isEmpty()) { if (answer == null || answer.isEmpty()) {
// invalidateState("connection"); // invalidateState("connection");
updateState(CONNECTED_STATE, false); updateState(CONNECTED_STATE, false);

View File

@ -42,7 +42,7 @@ public class MKSVacDevice extends PortSensor<Double> {
} }
private String talk(String requestContent) throws ControlException { private String talk(String requestContent) throws ControlException {
String answer = getHandler().sendAndWait(String.format("@%s%s;FF", getDeviceAddress(), requestContent), timeout()); String answer = sendAndWait(String.format("@%s%s;FF", getDeviceAddress(), requestContent), timeout());
Matcher match = Pattern.compile("@" + getDeviceAddress() + "ACK(.*);FF").matcher(answer); Matcher match = Pattern.compile("@" + getDeviceAddress() + "ACK(.*);FF").matcher(answer);
if (match.matches()) { if (match.matches()) {
@ -55,7 +55,7 @@ public class MKSVacDevice extends PortSensor<Double> {
@Override @Override
protected PortHandler buildHandler(String portName) throws ControlException { protected PortHandler buildHandler(String portName) throws ControlException {
PortHandler handler = super.buildHandler(portName); PortHandler handler = super.buildHandler(portName);
handler.setDelimeter(";FF"); handler.setDelimiter(";FF");
return handler; return handler;
} }

View File

@ -41,7 +41,7 @@ public class MeradatVacDevice extends PortSensor<Double> {
@Override @Override
protected PortHandler buildHandler(String portName) throws ControlException { protected PortHandler buildHandler(String portName) throws ControlException {
PortHandler newHandler = super.buildHandler(portName); PortHandler newHandler = super.buildHandler(portName);
newHandler.setDelimeter("\r\n"); newHandler.setDelimiter("\r\n");
return newHandler; return newHandler;
} }
@ -65,7 +65,7 @@ public class MeradatVacDevice extends PortSensor<Double> {
checksum += aByte; checksum += aByte;
} }
String val = Integer.toHexString(-checksum); String val = Integer.toHexString(-checksum);
val = val.substring(val.length()-2).toUpperCase(); val = val.substring(val.length() - 2).toUpperCase();
if (val.length() < 2) { if (val.length() < 2) {
val = "0" + val; val = "0" + val;
} }
@ -90,7 +90,7 @@ public class MeradatVacDevice extends PortSensor<Double> {
@Override @Override
protected synchronized Double doMeasure() throws Exception { protected synchronized Double doMeasure() throws Exception {
String answer = getHandler().sendAndWait(query, timeout(), phrase -> phrase.startsWith(base)); String answer = sendAndWait(query, timeout(), phrase -> phrase.startsWith(base));
if (answer.isEmpty()) { if (answer.isEmpty()) {
this.progressUpdate("No signal"); this.progressUpdate("No signal");

View File

@ -130,7 +130,7 @@ public class VacCollectorView extends DeviceViewConnection<VacCollectorDevice> i
} }
@Override @Override
public void open(VacCollectorDevice device) throws Exception { public void open(VacCollectorDevice device) {
super.open(device); super.open(device);
device.getSensors().stream().map((sensor) -> { device.getSensors().stream().map((sensor) -> {
VacuumeterView view; VacuumeterView view;