PKT8 - working

This commit is contained in:
Alexander Nozik 2016-09-29 13:52:24 +03:00
parent d3f3483bd1
commit a33457d025
7 changed files with 128 additions and 177 deletions

View File

@ -12,5 +12,13 @@ dependencies {
compile 'de.jensd:shichimifx:1.0.5'
compile project(':dataforge-control')
compile project(':dataforge-storage')
compile project(':dataforge-plots')
compile project(':dataforge-plots:plots-jfc')
}
task debug(dependsOn: classes, type: JavaExec) {
main mainClass
args "--debug=true"
classpath = sourceSets.main.runtimeClasspath
description "Start application in debug mode with default virtual port"
group "debug"
}

View File

@ -17,6 +17,7 @@ package inr.numass.cryotemp;
import ch.qos.logback.classic.Level;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.io.MetaFileReader;
import hep.dataforge.storage.commons.StorageManager;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
@ -25,7 +26,9 @@ import javafx.scene.Scene;
import javafx.stage.Stage;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.Locale;
/**
@ -43,7 +46,7 @@ public class PKT8App extends Application {
}
@Override
public void start(Stage primaryStage) throws IOException, ControlException {
public void start(Stage primaryStage) throws IOException, ControlException, ParseException {
Locale.setDefault(Locale.US);// чтобы отделение десятичных знаков было точкой
ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.INFO);
@ -68,6 +71,12 @@ public class PKT8App extends Application {
// primaryStage.setResizable(false);
primaryStage.show();
if(getParameters().getNamed().containsKey("cfgFile")){
controller.setConfig(MetaFileReader.read(new File(getParameters().getNamed().get("cfgFile"))));
} else if (Boolean.parseBoolean(getParameters().getNamed().getOrDefault("debug","false"))){
controller.loadTestConfig();
}
}
@Override

View File

@ -76,6 +76,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
getLogger().warn("No channels defined in configuration");
}
super.init();
//update parameters from meta
if (meta().hasValue("pga")) {
getLogger().info("Setting dynamic range to " + meta().getInt("pga"));
@ -90,22 +91,27 @@ public class PKT8Device extends PortSensor<PKT8Result> {
setSPS(meta().getInt("sps", 0));
setBUF(meta().getInt("abuf", 100));
super.init();
}
@Override
public void shutdown() throws ControlException {
super.shutdown();
collector.clear();
collector = null;
}
@Override
protected PortHandler buildHandler(String portName) throws ControlException {
PortHandler handler;
//setup connection
if (meta().hasNode("debug")) {
handler = new PKT8VirtualPort("PKT8", meta().getNode("debug"));
if ("virtual".equals(portName)) {
getLogger().info("Starting {} using virtual debug port", getName());
handler = new PKT8VirtualPort("PKT8", meta().getNodeOrEmpty("debug"));
} else {
handler = super.buildHandler(portName);
}
handler.setDelimeter("\n");
//clearing PKT queue
handler.send("p");
handler.sendAndWait("p", null, 1000);
return handler;
}
@ -115,7 +121,13 @@ public class PKT8Device extends PortSensor<PKT8Result> {
private void setBUF(int buf) throws ControlException {
getLogger().info("Setting avaraging buffer size to " + buf);
String response = getHandler().sendAndWait("b" + buf, null, 400).trim();
String response;
try {
response = getHandler().sendAndWait("b" + buf, null, 400).trim();
} catch (Exception ex) {
response = ex.getMessage();
}
if (response.contains("=")) {
updateState(ABUF, Integer.parseInt(response.substring(14)));
// getLogger().info("successfully set buffer size to {}", this.abuf);
@ -168,11 +180,11 @@ public class PKT8Device extends PortSensor<PKT8Result> {
* '0' : ± 5 В '1' : ± 2,5 В '2' : ± 1,25 В '3' : ± 0,625 В '4' : ± 312.5 мВ
* '5' : ± 156,25 мВ '6' : ± 78,125 мВ
*
* @param sps
* @param pga
* @return
*/
private String pgaToStr(int sps) {
switch (sps) {
private String pgaToStr(int pga) {
switch (pga) {
case 0:
return "± 5 V";
case 1:
@ -198,7 +210,12 @@ public class PKT8Device extends PortSensor<PKT8Result> {
private void setSPS(int sps) throws ControlException {
getLogger().info("Setting sampling rate to " + spsToStr(sps));
String response = getHandler().sendAndWait("v" + sps, null, 400).trim();
String response;
try {
response = getHandler().sendAndWait("v" + sps, null, 400).trim();
} catch (Exception ex) {
response = ex.getMessage();
}
if (response.contains("=")) {
updateState(SPS, Integer.parseInt(response.substring(4)));
// getLogger().info("successfully sampling rate to {}", spsToStr(this.sps));
@ -216,7 +233,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
}
private void setupStorage() {
if (meta().hasNode("storage") && collector != null) {
if (meta().hasNode("storage")) {
try {
Storage storage = StorageFactory.buildStorage(getContext(), meta().getNode("storage", Meta.empty()));
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
@ -253,16 +270,29 @@ public class PKT8Device extends PortSensor<PKT8Result> {
@Override
protected Measurement<PKT8Result> createMeasurement() throws MeasurementException {
if (this.getMeasurement() != null) {
return this.getMeasurement();
} else {
try {
return new PKT8Measurement(getHandler());
} catch (ControlException e) {
throw new MeasurementException(e);
}
}
}
@Override
public Measurement<PKT8Result> startMeasurement() throws MeasurementException {
//clearing PKT queue
try {
getHandler().send("p");
getHandler().sendAndWait("p", null, 1000);
} catch (ControlException e) {
// throw new MeasurementException(e);
}
if(collector == null){
setupStorage();
}
return super.startMeasurement();
}
@ -282,7 +312,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
handler.send("s");
afterStart();
} catch (PortException ex) {
throw new RuntimeException(ex);
error("Failed to start measurement", ex);
}
}
@ -291,7 +321,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
try {
getHandler().send("p");
if (collector != null) {
collector.cancel();
collector.clear();
}
return true;
} catch (Exception ex) {
@ -324,7 +354,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
} else {
result(new PKT8Result(designation, rawValue, -1));
}
setMeasurementState(MeasurementState.OK);
}
}
}
@ -335,40 +365,3 @@ public class PKT8Device extends PortSensor<PKT8Result> {
}
}
}
/*
//setup storage
try {
Storage storage = getPrimaryStorage(measurement);
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
// Building data format
TableFormatBuilder TableFormatBuilder = new TableFormatBuilder()
.addTime("timestamp");
List<String> names = new ArrayList<>();
for (PKT8Channel channel : channels.values()) {
TableFormatBuilder.addNumber(channel.getName());
names.add(channel.getName());
}
this.pointLoader = LoaderFactory.buildPointLoder(storage, "cryotemp_" + suffix, "", "timestamp", TableFormatBuilder.build());
Duration duration = Duration.parse(meta().getString("averagingDuration", "PT30S"));
collector = new RegularPointCollector((dp) -> {
if (pointLoader != null) {
try {
getLogger().debug("Point measurement complete. Pushing...");
pointLoader.push(dp);
} catch (StorageException ex) {
getLogger().error("Error while pushing point to loader", ex);
}
}
}, duration, names);
} catch (StorageException ex) {
getLogger().error("Can't setup storage", ex);
}
*/

View File

@ -15,31 +15,28 @@
*/
package inr.numass.cryotemp;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import de.jensd.shichimifx.utils.SplitPaneDividerSlider;
import hep.dataforge.context.GlobalContext;
import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.MeasurementListener;
import hep.dataforge.exceptions.ControlException;
import hep.dataforge.fx.ConsoleFragment;
import hep.dataforge.io.MetaFileReader;
import hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaBuilder;
import hep.dataforge.meta.MetaUtils;
import hep.dataforge.plots.PlotUtils;
import hep.dataforge.plots.data.TimePlottable;
import hep.dataforge.plots.data.TimePlottableGroup;
import hep.dataforge.plots.data.XYPlottable;
import hep.dataforge.plots.fx.FXPlotFrame;
import hep.dataforge.plots.fx.PlotContainer;
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
import hep.dataforge.values.Value;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.AnchorPane;
import javafx.stage.FileChooser;
@ -62,28 +59,24 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
public static final String DEFAULT_CONFIG_LOCATION = "devices.xml";
private PKT8Device device;
private JFreeChartFrame plotFrame;
private FXPlotFrame<XYPlottable> plotFrame;
private TimePlottableGroup plottables;
private Meta currentPlotConfig;
ConsoleFragment consoleFragment;
@FXML
private Button loadConfigButton;
@FXML
private SplitPane consoleSplitPane;
@FXML
private TextArea logArea;
@FXML
private ToggleButton startStopButton;
@FXML
private AnchorPane plotArea;
@FXML
private ToggleButton consoleButton;
@Override
public void close() throws Exception {
if (device != null) {
device.stopMeasurement(true);
device.shutdown();
}
}
@ -94,11 +87,8 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
@Override
public void initialize(URL url, ResourceBundle rb) {
setupPlotFrame(null);
SplitPaneDividerSlider slider = new SplitPaneDividerSlider(consoleSplitPane, 0, SplitPaneDividerSlider.Direction.DOWN);
consoleButton.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
slider.setAimContentVisible(newValue);
});
slider.setAimContentVisible(false);
this.consoleFragment = new ConsoleFragment();
consoleFragment.bindTo(consoleButton);
}
@FXML
@ -117,7 +107,7 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
}
}
private void loadTestConfig() throws ControlException {
public void loadTestConfig() throws ControlException {
try {
Meta testConfig = MetaFileReader
.read(new File(getClass().getResource("/config/defaultConfig.xml").toURI()));
@ -157,16 +147,10 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
private void setupPlotFrame(Meta plotFrameMeta) {
plottables = new TimePlottableGroup();
plotArea.getChildren().clear();
Meta plotConfig;
if (plotFrameMeta != null) {
plotConfig = new MetaBuilder(plotFrameMeta)
.setValue("xAxis.timeAxis", true);
} else {
plotConfig = new MetaBuilder("plotFrame")
.setValue("xAxis.timeAxis", true);
}
plotFrame = new JFreeChartFrame(plotConfig);
plotFrame.display(plotArea);
plotFrame = new JFreeChartFrame(plotFrameMeta);
PlotUtils.setXAxis(plotFrame, "timestamp", null, "time");
PlotContainer container = PlotContainer.anchorTo(plotArea);
container.setPlot(plotFrame);
}
public void setupDevice(Meta deviceMeta) throws ControlException {
@ -175,27 +159,12 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
device.shutdown();
}
this.device = new PKT8Device("PKT8", GlobalContext.instance(), deviceMeta);
this.device = new PKT8Device(deviceMeta.getString("port", "virtual"));
device.configure(deviceMeta);
device.addDeviceListener(this);
device.addMeasurementListener(this);
logArea.appendText("Starting log...\n");
Appender<ILoggingEvent> appender = new AppenderBase<ILoggingEvent>() {
// private final DateTimeFormatter formatter = DateTimeFormatter.ISO_TIME;
@Override
protected void append(ILoggingEvent e) {
logArea.appendText(String.format("%s > (%s) [%s] %s%n",
e.getLoggerName(),
Instant.now().toString(),
e.getLevel(),
e.getFormattedMessage()));
}
};
appender.start();
device.getLogger().addAppender(appender);
consoleFragment.addLogHandler(device.getLogger());
device.init();
}
@ -203,18 +172,22 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
@Override
public void notifyDeviceInitialized(Device device) {
Collection<PKT8Channel> channels = this.device.getChanels();
for (PKT8Channel channel : channels) {
if (!plottables.hasPlottable(channel.getName())) {
//plot config from device configuration
//Do not use view config here, it is applyed separately
channels.stream()
.filter(channel -> !plottables.hasPlottable(channel.getName()))
.forEach(channel -> {
//plot config from device configuration
Meta deviceLineMeta = channel.meta().getNode("plot", channel.meta());
//Do not use view config here, it is applyed separately
TimePlottable plottable = new TimePlottable(channel.getName(), deviceLineMeta);
TimePlottable plottable = new TimePlottable(channel.getName());
plottable.configure(deviceLineMeta);
plottables.addPlottable(plottable);
plotFrame.add(plottable);
}
}
});
startStopButton.setDisable(false);
if (currentPlotConfig != null) {
@ -259,17 +232,20 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
}
@FXML
private void onStartStopClick(ActionEvent event) {
if (device != null) {
try {
if (startStopButton.isSelected()) {
device.startMeasurement();
device.startMeasurement()
.addListener(this);
} else {
//in case device started
if (device.isMeasuring()) {
device.getMeasurement().removeListener(this);
device.stopMeasurement(false);
}
}
} catch (ControlException ex) {
}

View File

@ -6,7 +6,6 @@
package inr.numass.cryotemp;
import hep.dataforge.control.ports.VirtualPort;
import hep.dataforge.exceptions.PortException;
import hep.dataforge.meta.Annotated;
import hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaUtils;
@ -21,18 +20,10 @@ import java.util.Random;
*/
public class PKT8VirtualPort extends VirtualPort implements Annotated {
private final Meta meta;
private final Random generator = new Random();
private final String id;
public PKT8VirtualPort(String portName, Meta meta) {
id = portName;
this.meta = meta;
}
@Override
public Meta meta() {
return meta;
super.configure(meta).configureValue("id", portName);
}
@Override
@ -70,24 +61,10 @@ public class PKT8VirtualPort extends VirtualPort implements Annotated {
}
}
@Override
public void open() throws PortException {
}
@Override
public boolean isOpen() {
return true;
}
@Override
public String getPortId() {
return id;
}
@Override
public void close() throws Exception {
cancelByTag("measurement");
super.close();
}
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<device>
<storage path="D:\\temp\\cryo"/>
<connection ip="192.168.111.137" port="4001"/>
<!--<connection ip="192.168.111.137" port="4001"/>-->
<abuf>120</abuf>
<channel designation="a" name="a-channel" r0="1000" transformationType="hyperbolic" coefs="[1.0,1.0]"
color="black"/>

View File

@ -16,34 +16,22 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" id="AnchorPane" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/8" fx:controller="inr.numass.cryotemp.PKT8MainViewController">
<children>
<SplitPane fx:id="consoleSplitPane" dividerPositions="0.8" layoutX="184.0" layoutY="62.0" orientation="VERTICAL"
prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0">
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.cryotemp.PKT8MainViewController">
<center>
<AnchorPane fx:id="plotArea" />
</center>
<top>
<ToolBar BorderPane.alignment="CENTER">
<items>
<AnchorPane fx:id="plotArea" minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0"/>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="94.0" prefWidth="598.0">
<children>
<TextArea fx:id="logArea" editable="false" layoutX="38.0" layoutY="-75.0" prefHeight="200.0"
prefWidth="200.0" wrapText="true" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
</children>
</AnchorPane>
</items>
</SplitPane>
<ToolBar prefHeight="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<ToggleButton fx:id="startStopButton" disable="true" mnemonicParsing="false"
onAction="#onStartStopClick" prefWidth="50.0" text="Start"/>
<Separator orientation="VERTICAL"/>
<Button fx:id="loadConfigButton" mnemonicParsing="false" onAction="#onLoadConfigClick"
text="Load config"/>
<ToggleButton fx:id="consoleButton" contentDisplay="CENTER" mnemonicParsing="false" text="Console"/>
<ToggleButton fx:id="startStopButton" disable="true" mnemonicParsing="false" onAction="#onStartStopClick" prefWidth="50.0" text="Start" />
<Separator orientation="VERTICAL" />
<Button fx:id="loadConfigButton" mnemonicParsing="false" onAction="#onLoadConfigClick" text="Load config" />
<ToggleButton fx:id="consoleButton" contentDisplay="CENTER" mnemonicParsing="false" text="Console" />
</items>
</ToolBar>
</children>
</AnchorPane>
</top>
</BorderPane>