PKT8
This commit is contained in:
parent
e10b2393b6
commit
d3f3483bd1
@ -1,114 +0,0 @@
|
|||||||
package inr.numass.cryotemp;
|
|
||||||
|
|
||||||
import hep.dataforge.control.devices.PortSensor;
|
|
||||||
import hep.dataforge.control.measurements.AbstractMeasurement;
|
|
||||||
import hep.dataforge.control.measurements.Measurement;
|
|
||||||
import hep.dataforge.exceptions.ControlException;
|
|
||||||
import hep.dataforge.exceptions.MeasurementException;
|
|
||||||
import hep.dataforge.tables.DataPoint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by darksnake on 28-Sep-16.
|
|
||||||
*/
|
|
||||||
public class PKT8 extends PortSensor<DataPoint> {
|
|
||||||
|
|
||||||
public static final String PGA = "pga";
|
|
||||||
public static final String SPS = "sps";
|
|
||||||
public static final String ABUF = "abuf";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Measurement<DataPoint> createMeasurement() throws MeasurementException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Object computeState(String stateName) throws ControlException {
|
|
||||||
return super.computeState(stateName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* '0' : 2,5 SPS '1' : 5 SPS '2' : 10 SPS '3' : 25 SPS '4' : 50 SPS '5' :
|
|
||||||
* 100 SPS '6' : 500 SPS '7' : 1 kSPS '8' : 3,75 kSPS
|
|
||||||
*
|
|
||||||
* @param sps
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String spsToStr(int sps) {
|
|
||||||
switch (sps) {
|
|
||||||
case 0:
|
|
||||||
return "2,5 SPS";
|
|
||||||
case 1:
|
|
||||||
return "5 SPS";
|
|
||||||
case 2:
|
|
||||||
return "10 SPS";
|
|
||||||
case 3:
|
|
||||||
return "25 SPS";
|
|
||||||
case 4:
|
|
||||||
return "50 SPS";
|
|
||||||
case 5:
|
|
||||||
return "100 SPS";
|
|
||||||
case 6:
|
|
||||||
return "500 SPS";
|
|
||||||
case 7:
|
|
||||||
return "1 kSPS";
|
|
||||||
case 8:
|
|
||||||
return "3.75 kSPS";
|
|
||||||
default:
|
|
||||||
return "unknown value";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* '0' : ± 5 В '1' : ± 2,5 В '2' : ± 1,25 В '3' : ± 0,625 В '4' : ± 312.5 мВ
|
|
||||||
* '5' : ± 156,25 мВ '6' : ± 78,125 мВ
|
|
||||||
*
|
|
||||||
* @param sps
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String pgaToStr(int sps) {
|
|
||||||
switch (sps) {
|
|
||||||
case 0:
|
|
||||||
return "± 5 V";
|
|
||||||
case 1:
|
|
||||||
return "± 2,5 V";
|
|
||||||
case 2:
|
|
||||||
return "± 1,25 V";
|
|
||||||
case 3:
|
|
||||||
return "± 0,625 V";
|
|
||||||
case 4:
|
|
||||||
return "± 312.5 mV";
|
|
||||||
case 5:
|
|
||||||
return "± 156,25 mV";
|
|
||||||
case 6:
|
|
||||||
return "± 78,125 mV";
|
|
||||||
default:
|
|
||||||
return "unknown value";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSPS() {
|
|
||||||
return spsToStr(sps);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPGA() {
|
|
||||||
return pgaToStr(pga);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getABUF() {
|
|
||||||
return Integer.toString(abuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class PKT8Measurement extends AbstractMeasurement<DataPoint> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean stop(boolean force) throws MeasurementException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Alexander Nozik.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Annotated;
|
||||||
|
import hep.dataforge.meta.Meta;
|
||||||
|
import hep.dataforge.meta.MetaBuilder;
|
||||||
|
import hep.dataforge.names.Named;
|
||||||
|
import hep.dataforge.values.Value;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by darksnake on 28-Sep-16.
|
||||||
|
*/
|
||||||
|
public class PKT8Channel implements Named, Annotated {
|
||||||
|
|
||||||
|
private final Meta meta;
|
||||||
|
private final Function<Double, Double> transformation;
|
||||||
|
|
||||||
|
public PKT8Channel(String name) {
|
||||||
|
this.meta = new MetaBuilder("channel")
|
||||||
|
.putValue("name", name);
|
||||||
|
transformation = (d) -> d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PKT8Channel(Meta meta) {
|
||||||
|
this.meta = meta;
|
||||||
|
|
||||||
|
String transformationType = meta.getString("transformationType", "default");
|
||||||
|
if (meta.hasValue("coefs")) {
|
||||||
|
switch (transformationType) {
|
||||||
|
case "default":
|
||||||
|
case "hyperbolic":
|
||||||
|
List<Value> coefs = meta.getValue("coefs").listValue();
|
||||||
|
double r0 = meta.getDouble("r0", 1000);
|
||||||
|
transformation = (r) -> {
|
||||||
|
if (coefs == null) {
|
||||||
|
return -1d;
|
||||||
|
} else {
|
||||||
|
double res = 0;
|
||||||
|
for (int i = 0; i < coefs.size(); i++) {
|
||||||
|
res += coefs.get(i).doubleValue() * Math.pow(r0 / r, i);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unknown transformation type");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//identity transformation
|
||||||
|
transformation = (d) -> d;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return meta().getString("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Meta meta() {
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String description() {
|
||||||
|
return meta().getString("description", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param r negative if temperature transformation not defined
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public double getTemperature(double r) {
|
||||||
|
return transformation.apply(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PKT8Result evaluate(double r) {
|
||||||
|
return new PKT8Result(getName(), r, getTemperature(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,103 +15,48 @@
|
|||||||
*/
|
*/
|
||||||
package inr.numass.cryotemp;
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
import hep.dataforge.context.Context;
|
|
||||||
import hep.dataforge.control.collectors.RegularPointCollector;
|
import hep.dataforge.control.collectors.RegularPointCollector;
|
||||||
import hep.dataforge.control.devices.PortSensor;
|
import hep.dataforge.control.devices.PortSensor;
|
||||||
import hep.dataforge.control.measurements.AbstractMeasurement;
|
import hep.dataforge.control.measurements.AbstractMeasurement;
|
||||||
|
import hep.dataforge.control.measurements.Measurement;
|
||||||
import hep.dataforge.control.ports.PortHandler;
|
import hep.dataforge.control.ports.PortHandler;
|
||||||
import hep.dataforge.control.ports.TcpPortHandler;
|
|
||||||
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.PortException;
|
||||||
import hep.dataforge.exceptions.StorageException;
|
import hep.dataforge.exceptions.StorageException;
|
||||||
import hep.dataforge.meta.Annotated;
|
|
||||||
import hep.dataforge.meta.Meta;
|
import hep.dataforge.meta.Meta;
|
||||||
import hep.dataforge.meta.MetaBuilder;
|
|
||||||
import hep.dataforge.names.Named;
|
|
||||||
import hep.dataforge.storage.api.PointLoader;
|
import hep.dataforge.storage.api.PointLoader;
|
||||||
import hep.dataforge.storage.api.Storage;
|
import hep.dataforge.storage.api.Storage;
|
||||||
import hep.dataforge.storage.commons.LoaderFactory;
|
import hep.dataforge.storage.commons.LoaderFactory;
|
||||||
import hep.dataforge.tables.DataPoint;
|
import hep.dataforge.storage.commons.StorageFactory;
|
||||||
import hep.dataforge.tables.TableTableFormatBuilder;
|
import hep.dataforge.tables.TableFormatBuilder;
|
||||||
import hep.dataforge.values.Value;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A device controller for Dubna PKT 8 cryogenic thermometry device
|
* A device controller for Dubna PKT 8 cryogenic thermometry device
|
||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
public class PKT8Device extends PortSensor<DataPoint> implements PortHandler.PortController {
|
public class PKT8Device extends PortSensor<PKT8Result> {
|
||||||
|
|
||||||
private static final String[] CHANNEL_DESIGNATIONS = {"a", "b", "c", "d", "e", "f", "g", "h"};
|
private static final String[] CHANNEL_DESIGNATIONS = {"a", "b", "c", "d", "e", "f", "g", "h"};
|
||||||
|
|
||||||
|
public static final String PGA = "pga";
|
||||||
|
public static final String SPS = "sps";
|
||||||
|
public static final String ABUF = "abuf";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The key is the letter (a,b,c,d...) as in measurements
|
* The key is the letter (a,b,c,d...) as in measurements
|
||||||
*/
|
*/
|
||||||
private final Map<String, Channel> channels = new HashMap<>();
|
private final Map<String, PKT8Channel> channels = new HashMap<>();
|
||||||
private PointLoader pointLoader;
|
// private PointLoader pointLoader;
|
||||||
private RegularPointCollector collector;
|
private RegularPointCollector collector;
|
||||||
private boolean isStarted = false;
|
|
||||||
private PortHandler handler;
|
|
||||||
private int sps = -1;
|
|
||||||
private int pga = -1;
|
|
||||||
private int abuf = -1;
|
|
||||||
|
|
||||||
public PKT8Device(String name, Context context, Meta annotation) {
|
public PKT8Device(String portName) {
|
||||||
super(name, context, annotation);
|
super(portName);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start measurement
|
|
||||||
*
|
|
||||||
* @throws ControlException
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doStart(Meta measurement) throws ControlException {
|
|
||||||
|
|
||||||
// Meta meta = new MetaChain("device", measurement.meta(),meta());
|
|
||||||
if (!isStarted) {
|
|
||||||
//setup storage
|
|
||||||
|
|
||||||
try {
|
|
||||||
Storage storage = getPrimaryStorage(measurement);
|
|
||||||
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
|
|
||||||
|
|
||||||
// Building data format
|
|
||||||
TableTableFormatBuilder TableFormatBuilder = new TableTableFormatBuilder()
|
|
||||||
.addTime("timestamp");
|
|
||||||
List<String> names = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Channel channel : this.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.send("s");
|
|
||||||
isStarted = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -121,36 +66,22 @@ public class PKT8Device extends PortSensor<DataPoint> implements PortHandler.Por
|
|||||||
if (meta().hasNode("channel")) {
|
if (meta().hasNode("channel")) {
|
||||||
for (Meta node : meta().getNodes("channel")) {
|
for (Meta node : meta().getNodes("channel")) {
|
||||||
String designation = node.getString("designation", "default");
|
String designation = node.getString("designation", "default");
|
||||||
this.channels.put(designation, new Channel(node));
|
this.channels.put(designation, new PKT8Channel(node));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//set default channel configuration
|
//set default channel configuration
|
||||||
for (String designation : CHANNEL_DESIGNATIONS) {
|
for (String designation : CHANNEL_DESIGNATIONS) {
|
||||||
channels.put(designation, new Channel(designation));
|
channels.put(designation, new PKT8Channel(designation));
|
||||||
}
|
}
|
||||||
getLogger().warn("No channels defined in configuration");
|
getLogger().warn("No channels defined in configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
//setup connection
|
|
||||||
if (meta().hasNode("debug")) {
|
|
||||||
handler = new PKT8VirtualPort("PKT8", meta().getNode("debug"));
|
|
||||||
} else {
|
|
||||||
String ip = this.meta().getString("connection.ip", "127.0.0.1");
|
|
||||||
int port = this.meta().getInt("connection.port", 4001);
|
|
||||||
handler = new TcpPortHandler(ip, port, getName());
|
|
||||||
}
|
|
||||||
handler.setDelimeter("\n");
|
|
||||||
handler.holdBy(this);
|
|
||||||
handler.open();
|
|
||||||
handler.send("p");
|
|
||||||
handler.sendAndWait("p", null, 1000);
|
|
||||||
|
|
||||||
//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 = handler.sendAndWait("g" + meta().getInt("pga"), null, 400).trim();
|
String response = getHandler().sendAndWait("g" + meta().getInt("pga"), null, 400).trim();
|
||||||
if (response.contains("=")) {
|
if (response.contains("=")) {
|
||||||
this.pga = Integer.parseInt(response.substring(4));
|
updateState(PGA, Integer.parseInt(response.substring(4)));
|
||||||
} else {
|
} else {
|
||||||
getLogger().error("Setting pga failsed with message: " + response);
|
getLogger().error("Setting pga failsed with message: " + response);
|
||||||
}
|
}
|
||||||
@ -163,88 +94,42 @@ public class PKT8Device extends PortSensor<DataPoint> implements PortHandler.Por
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() throws ControlException {
|
protected PortHandler buildHandler(String portName) throws ControlException {
|
||||||
stop();
|
PortHandler handler;
|
||||||
try {
|
//setup connection
|
||||||
this.handler.unholdBy(this);
|
if (meta().hasNode("debug")) {
|
||||||
this.handler.close();
|
handler = new PKT8VirtualPort("PKT8", meta().getNode("debug"));
|
||||||
|
} else {
|
||||||
} catch (Exception ex) {
|
handler = super.buildHandler(portName);
|
||||||
throw new ControlException(ex);
|
|
||||||
}
|
}
|
||||||
super.shutdown();
|
handler.setDelimeter("\n");
|
||||||
|
//clearing PKT queue
|
||||||
|
handler.send("p");
|
||||||
|
handler.sendAndWait("p", null, 1000);
|
||||||
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Channel> getChanels() {
|
public Collection<PKT8Channel> getChanels() {
|
||||||
return this.channels.values();
|
return this.channels.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBUF(int buf) throws PortException {
|
private void setBUF(int buf) throws ControlException {
|
||||||
getLogger().info("Setting avaraging buffer size to " + buf);
|
getLogger().info("Setting avaraging buffer size to " + buf);
|
||||||
String response = handler.sendAndWait("b" + buf, null, 400).trim();
|
String response = getHandler().sendAndWait("b" + buf, null, 400).trim();
|
||||||
if (response.contains("=")) {
|
if (response.contains("=")) {
|
||||||
this.abuf = Integer.parseInt(response.substring(14));
|
updateState(ABUF, Integer.parseInt(response.substring(14)));
|
||||||
getLogger().info("successfully set buffer size to {}", this.abuf);
|
// getLogger().info("successfully set buffer size to {}", this.abuf);
|
||||||
} else {
|
} else {
|
||||||
getLogger().error("Setting averaging buffer failsed with message: " + response);
|
getLogger().error("Setting averaging buffer failsed with message: " + response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void changeParameters(int sps, int abuf) throws ControlException {
|
||||||
public void doStop() throws ControlException {
|
stopMeasurement(false);
|
||||||
handler.send("p");
|
|
||||||
isStarted = false;
|
|
||||||
if (collector != null) {
|
|
||||||
collector.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changeParameters(int sps, int abuf) {
|
|
||||||
this.executor.submit(() -> {
|
|
||||||
try {
|
|
||||||
stop();
|
|
||||||
//setting sps
|
//setting sps
|
||||||
setSPS(sps);
|
setSPS(sps);
|
||||||
//setting buffer
|
//setting buffer
|
||||||
setBUF(abuf);
|
setBUF(abuf);
|
||||||
start();
|
|
||||||
} catch (ControlException ex) {
|
|
||||||
getLogger().error("Control error", ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(String message) {
|
|
||||||
String trimmed = message.trim();
|
|
||||||
|
|
||||||
if (isStarted) {
|
|
||||||
if (trimmed.equals("stopped")) {
|
|
||||||
isStarted = false;
|
|
||||||
getLogger().info("Measurement paused");
|
|
||||||
} else {
|
|
||||||
String designation = trimmed.substring(0, 1);
|
|
||||||
double rawValue = Double.parseDouble(trimmed.substring(1)) / 100;
|
|
||||||
|
|
||||||
if (channels.containsKey(designation)) {
|
|
||||||
Channel channel = channels.get(designation);
|
|
||||||
notifyMeasurementComplete(channel.getName(), rawValue, channel.getTemperature(rawValue));
|
|
||||||
collector.put(channel.getName(), channel.getTemperature(rawValue));
|
|
||||||
} else {
|
|
||||||
notifyMeasurementComplete(designation, rawValue, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyMeasurementComplete(String channel, double rawValue, double temperature) {
|
|
||||||
measurementResult(null, new Data(channel, rawValue, temperature));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void error(String errorMessage, Throwable error) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -308,120 +193,182 @@ public class PKT8Device extends PortSensor<DataPoint> implements PortHandler.Por
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getSPS() {
|
public String getSPS() {
|
||||||
return spsToStr(sps);
|
return getState(SPS).stringValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSPS(int sps) throws PortException {
|
private void setSPS(int sps) throws ControlException {
|
||||||
getLogger().info("Setting sampling rate to " + spsToStr(sps));
|
getLogger().info("Setting sampling rate to " + spsToStr(sps));
|
||||||
String response = handler.sendAndWait("v" + sps, null, 400).trim();
|
String response = getHandler().sendAndWait("v" + sps, null, 400).trim();
|
||||||
if (response.contains("=")) {
|
if (response.contains("=")) {
|
||||||
this.sps = Integer.parseInt(response.substring(4));
|
updateState(SPS, Integer.parseInt(response.substring(4)));
|
||||||
getLogger().info("successfully sampling rate to {}", spsToStr(this.sps));
|
// getLogger().info("successfully sampling rate to {}", spsToStr(this.sps));
|
||||||
} else {
|
} else {
|
||||||
getLogger().error("Setting sps failsed with message: " + response);
|
getLogger().error("Setting sps failsed with message: " + response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPGA() {
|
public String getPGA() {
|
||||||
return pgaToStr(pga);
|
return getState(PGA).stringValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getABUF() {
|
public String getABUF() {
|
||||||
return Integer.toString(abuf);
|
return getState(ABUF).stringValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Data {
|
private void setupStorage() {
|
||||||
|
if (meta().hasNode("storage") && collector != null) {
|
||||||
|
try {
|
||||||
|
Storage storage = StorageFactory.buildStorage(getContext(), meta().getNode("storage", Meta.empty()));
|
||||||
|
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
|
||||||
|
|
||||||
public String channel;
|
// Building data format
|
||||||
public double rawValue;
|
TableFormatBuilder TableFormatBuilder = new TableFormatBuilder()
|
||||||
public double temperature;
|
.addTime("timestamp");
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
|
||||||
public Data(String channel, double rawValue, double temperature) {
|
for (PKT8Channel channel : channels.values()) {
|
||||||
this.channel = channel;
|
TableFormatBuilder.addNumber(channel.getName());
|
||||||
this.rawValue = rawValue;
|
names.add(channel.getName());
|
||||||
this.temperature = temperature;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PointLoader 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Channel implements Named, Annotated {
|
|
||||||
|
|
||||||
private final Meta meta;
|
|
||||||
private final Function<Double, Double> transformation;
|
|
||||||
|
|
||||||
public Channel(String name) {
|
|
||||||
this.meta = new MetaBuilder("channel")
|
|
||||||
.putValue("name", name);
|
|
||||||
transformation = (d) -> d;
|
|
||||||
}
|
}
|
||||||
|
}, duration, names);
|
||||||
public Channel(Meta meta) {
|
} catch (StorageException ex) {
|
||||||
this.meta = meta;
|
getLogger().error("Can't setup storage", ex);
|
||||||
|
|
||||||
String transformationType = meta.getString("transformationType", "default");
|
|
||||||
if (meta.hasValue("coefs")) {
|
|
||||||
switch (transformationType) {
|
|
||||||
case "default":
|
|
||||||
case "hyperbolic":
|
|
||||||
List<Value> coefs = meta.getValue("coefs").listValue();
|
|
||||||
double r0 = meta.getDouble("r0", 1000);
|
|
||||||
transformation = (r) -> {
|
|
||||||
if (coefs == null) {
|
|
||||||
return -1d;
|
|
||||||
} else {
|
|
||||||
double res = 0;
|
|
||||||
for (int i = 0; i < coefs.size(); i++) {
|
|
||||||
res += coefs.get(i).doubleValue() * Math.pow(r0 / r, i);
|
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new RuntimeException("Unknown transformation type");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//identity transformation
|
|
||||||
transformation = (d) -> d;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
protected Measurement<PKT8Result> createMeasurement() throws MeasurementException {
|
||||||
return meta().getString("name");
|
try {
|
||||||
|
return new PKT8Measurement(getHandler());
|
||||||
|
} catch (ControlException e) {
|
||||||
|
throw new MeasurementException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Meta meta() {
|
public Measurement<PKT8Result> startMeasurement() throws MeasurementException {
|
||||||
return meta;
|
setupStorage();
|
||||||
|
return super.startMeasurement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String description() {
|
public class PKT8Measurement extends AbstractMeasurement<PKT8Result> implements PortHandler.PortController {
|
||||||
return meta().getString("description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
final PortHandler handler;
|
||||||
* @param r negative if temperature transformation not defined
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public double getTemperature(double r) {
|
|
||||||
return transformation.apply(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PKT8Measurement extends AbstractMeasurement<DataPoint> {
|
public PKT8Measurement(PortHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
|
try {
|
||||||
|
handler.holdBy(this);
|
||||||
|
handler.send("s");
|
||||||
|
afterStart();
|
||||||
|
} catch (PortException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean stop(boolean force) throws MeasurementException {
|
public boolean stop(boolean force) throws MeasurementException {
|
||||||
|
try {
|
||||||
|
getHandler().send("p");
|
||||||
|
if (collector != null) {
|
||||||
|
collector.cancel();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
error(ex);
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
handler.unholdBy(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(String message) {
|
||||||
|
String trimmed = message.trim();
|
||||||
|
|
||||||
|
if (isStarted()) {
|
||||||
|
if (trimmed.equals("stopped")) {
|
||||||
|
afterStop();
|
||||||
|
getLogger().info("Measurement stopped");
|
||||||
|
} else {
|
||||||
|
String designation = trimmed.substring(0, 1);
|
||||||
|
double rawValue = Double.parseDouble(trimmed.substring(1)) / 100;
|
||||||
|
|
||||||
|
if (channels.containsKey(designation)) {
|
||||||
|
PKT8Channel channel = channels.get(designation);
|
||||||
|
result(channel.evaluate(rawValue));
|
||||||
|
if (collector != null) {
|
||||||
|
collector.put(channel.getName(), channel.getTemperature(rawValue));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result(new PKT8Result(designation, rawValue, -1));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String errorMessage, Throwable error) {
|
||||||
|
super.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
*/
|
@ -22,19 +22,17 @@ import de.jensd.shichimifx.utils.SplitPaneDividerSlider;
|
|||||||
import hep.dataforge.context.GlobalContext;
|
import hep.dataforge.context.GlobalContext;
|
||||||
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.measurements.MeasurementDevice;
|
import hep.dataforge.control.measurements.Measurement;
|
||||||
import hep.dataforge.control.measurements.MeasurementListener;
|
import hep.dataforge.control.measurements.MeasurementListener;
|
||||||
import hep.dataforge.exceptions.ControlException;
|
import hep.dataforge.exceptions.ControlException;
|
||||||
import hep.dataforge.io.MetaFileReader;
|
import hep.dataforge.io.MetaFileReader;
|
||||||
import hep.dataforge.meta.Meta;
|
import hep.dataforge.meta.Meta;
|
||||||
import hep.dataforge.meta.MetaBuilder;
|
import hep.dataforge.meta.MetaBuilder;
|
||||||
import hep.dataforge.meta.MetaUtils;
|
import hep.dataforge.meta.MetaUtils;
|
||||||
import hep.dataforge.plots.XYPlotFrame;
|
import hep.dataforge.plots.data.TimePlottable;
|
||||||
import hep.dataforge.plots.data.DynamicPlottable;
|
import hep.dataforge.plots.data.TimePlottableGroup;
|
||||||
import hep.dataforge.plots.data.DynamicPlottableSet;
|
|
||||||
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
import hep.dataforge.plots.jfreechart.JFreeChartFrame;
|
||||||
import hep.dataforge.values.Value;
|
import hep.dataforge.values.Value;
|
||||||
import inr.numass.cryotemp.PKT8Device.Data;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
@ -60,12 +58,12 @@ import java.util.ResourceBundle;
|
|||||||
*
|
*
|
||||||
* @author darksnake
|
* @author darksnake
|
||||||
*/
|
*/
|
||||||
public class PKT8MainViewController implements Initializable, DeviceListener, MeasurementListener<Data>, AutoCloseable {
|
public class PKT8MainViewController implements Initializable, DeviceListener, MeasurementListener<PKT8Result>, AutoCloseable {
|
||||||
|
|
||||||
public static final String DEFAULT_CONFIG_LOCATION = "devices.xml";
|
public static final String DEFAULT_CONFIG_LOCATION = "devices.xml";
|
||||||
private PKT8Device device;
|
private PKT8Device device;
|
||||||
private XYPlotFrame plotFrame;
|
private JFreeChartFrame plotFrame;
|
||||||
private DynamicPlottableSet plottables;
|
private TimePlottableGroup plottables;
|
||||||
private Meta currentPlotConfig;
|
private Meta currentPlotConfig;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -85,7 +83,7 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
|
|||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
device.stop();
|
device.stopMeasurement(true);
|
||||||
device.shutdown();
|
device.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +155,7 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
|
|||||||
* Set o reset plot area
|
* Set o reset plot area
|
||||||
*/
|
*/
|
||||||
private void setupPlotFrame(Meta plotFrameMeta) {
|
private void setupPlotFrame(Meta plotFrameMeta) {
|
||||||
plottables = new DynamicPlottableSet();
|
plottables = new TimePlottableGroup();
|
||||||
plotArea.getChildren().clear();
|
plotArea.getChildren().clear();
|
||||||
Meta plotConfig;
|
Meta plotConfig;
|
||||||
if (plotFrameMeta != null) {
|
if (plotFrameMeta != null) {
|
||||||
@ -167,12 +165,13 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
|
|||||||
plotConfig = new MetaBuilder("plotFrame")
|
plotConfig = new MetaBuilder("plotFrame")
|
||||||
.setValue("xAxis.timeAxis", true);
|
.setValue("xAxis.timeAxis", true);
|
||||||
}
|
}
|
||||||
plotFrame = new JFreeChartFrame("plot", plotConfig).display(plotArea);
|
plotFrame = new JFreeChartFrame(plotConfig);
|
||||||
|
plotFrame.display(plotArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupDevice(Meta deviceMeta) throws ControlException {
|
public void setupDevice(Meta deviceMeta) throws ControlException {
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
device.stop();
|
device.stopMeasurement(true);
|
||||||
device.shutdown();
|
device.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,15 +202,15 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyDeviceInitialized(Device device) {
|
public void notifyDeviceInitialized(Device device) {
|
||||||
Collection<PKT8Device.Channel> channels = this.device.getChanels();
|
Collection<PKT8Channel> channels = this.device.getChanels();
|
||||||
for (PKT8Device.Channel channel : channels) {
|
for (PKT8Channel channel : channels) {
|
||||||
if (!plottables.hasPlottable(channel.getName())) {
|
if (!plottables.hasPlottable(channel.getName())) {
|
||||||
|
|
||||||
//plot config from device configuration
|
//plot config from device configuration
|
||||||
Meta deviceLineMeta = channel.meta().getNode("plot", channel.meta());
|
Meta deviceLineMeta = channel.meta().getNode("plot", channel.meta());
|
||||||
|
|
||||||
//Do not use view config here, it is applyed separately
|
//Do not use view config here, it is applyed separately
|
||||||
DynamicPlottable plottable = new DynamicPlottable(channel.getName(), deviceLineMeta);
|
TimePlottable plottable = new TimePlottable(channel.getName(), deviceLineMeta);
|
||||||
plottables.addPlottable(plottable);
|
plottables.addPlottable(plottable);
|
||||||
plotFrame.add(plottable);
|
plotFrame.add(plottable);
|
||||||
}
|
}
|
||||||
@ -232,10 +231,6 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
|
|||||||
startStopButton.setDisable(true);
|
startStopButton.setDisable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyDeviceStateChanged(Device device, String name, Value oldState, Value newState) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
// public void sendMessage(Device device, int priority, Meta message) {
|
// public void sendMessage(Device device, int priority, Meta message) {
|
||||||
@ -243,30 +238,37 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
|
|||||||
// logArea.appendText(String.format("%s > (%s) [%s] %s%n", device.getName(), Instant.now().toString(), tag, message));
|
// logArea.appendText(String.format("%s > (%s) [%s] %s%n", device.getName(), Instant.now().toString(), tag, message));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyMeasurementStarted(MeasurementDevice device, Meta measurement) {
|
public void onMeasurementResult(Measurement<PKT8Result> measurement, PKT8Result result, Instant time) {
|
||||||
|
plottables.put(result.channel, result.temperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMeasurementFailed(Measurement measurement, Throwable exception) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyMeasurementStopped(MeasurementDevice device) {
|
public void notifyDeviceStateChanged(Device device, String name, Value state) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyMeasurementResult(MeasurementDevice device, Meta measurement, Data measurementResult) {
|
public void evaluateDeviceException(Device device, String message, Throwable exception) {
|
||||||
plottables.put(measurementResult.channel, measurementResult.temperature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void onStartStopClick(ActionEvent event) {
|
private void onStartStopClick(ActionEvent event) {
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
try {
|
try {
|
||||||
if (startStopButton.isSelected()) {
|
if (startStopButton.isSelected()) {
|
||||||
device.start();
|
device.startMeasurement();
|
||||||
} else {
|
} else {
|
||||||
//in case device started
|
//in case device started
|
||||||
device.stop();
|
device.stopMeasurement(false);
|
||||||
}
|
}
|
||||||
} catch (ControlException ex) {
|
} catch (ControlException ex) {
|
||||||
|
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Alexander Nozik.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package inr.numass.cryotemp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by darksnake on 28-Sep-16.
|
||||||
|
*/
|
||||||
|
public class PKT8Result {
|
||||||
|
|
||||||
|
public String channel;
|
||||||
|
public double rawValue;
|
||||||
|
public double temperature;
|
||||||
|
|
||||||
|
public PKT8Result(String channel, double rawValue, double temperature) {
|
||||||
|
this.channel = channel;
|
||||||
|
this.rawValue = rawValue;
|
||||||
|
this.temperature = temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,9 +23,10 @@ public class PKT8VirtualPort extends VirtualPort implements Annotated {
|
|||||||
|
|
||||||
private final Meta meta;
|
private final Meta meta;
|
||||||
private final Random generator = new Random();
|
private final Random generator = new Random();
|
||||||
|
private final String id;
|
||||||
|
|
||||||
public PKT8VirtualPort(String portName, Meta meta) {
|
public PKT8VirtualPort(String portName, Meta meta) {
|
||||||
super(portName);
|
id = portName;
|
||||||
this.meta = meta;
|
this.meta = meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +80,11 @@ public class PKT8VirtualPort extends VirtualPort implements Annotated {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPortId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
cancelByTag("measurement");
|
cancelByTag("measurement");
|
||||||
|
Loading…
Reference in New Issue
Block a user