Control update
This commit is contained in:
parent
069c5422e0
commit
0fe0c1f1e1
@ -223,7 +223,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
|
||||
}
|
||||
|
||||
|
||||
override fun startMeasurement(oldMeta: Meta, newMeta: Meta) {
|
||||
fun setMeasurement(oldMeta: Meta, newMeta: Meta) {
|
||||
if (!oldMeta.isEmpty) {
|
||||
logger.warn("Trying to start measurement which is already started")
|
||||
}
|
||||
@ -317,7 +317,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
|
||||
// }
|
||||
//
|
||||
// @Throws(MeasurementException::class)
|
||||
// override fun startMeasurement(): Measurement<PKT8Result> {
|
||||
// override fun setMeasurement(): Measurement<PKT8Result> {
|
||||
// //clearing PKT queue
|
||||
// try {
|
||||
// send("p")
|
||||
@ -327,7 +327,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor<PKT8Result>(context,
|
||||
// // throw new MeasurementException(e);
|
||||
// }
|
||||
//
|
||||
// return super.startMeasurement()
|
||||
// return super.setMeasurement()
|
||||
// }
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package inr.numass.control
|
||||
|
||||
import hep.dataforge.control.devices.AbstractDevice
|
||||
import hep.dataforge.kodex.nullable
|
||||
import hep.dataforge.storage.api.TableLoader
|
||||
import hep.dataforge.storage.commons.StorageConnection
|
||||
import hep.dataforge.values.Values
|
||||
@ -14,7 +15,7 @@ class StorageHelper(private val device: AbstractDevice, private val loaderFactor
|
||||
private val loaderMap = HashMap<StorageConnection, TableLoader>()
|
||||
|
||||
fun push(point: Values) {
|
||||
if (!device.hasState("storing") || device.getState("storing").booleanValue()) {
|
||||
if (device.optBooleanState("storing").nullable == true) {
|
||||
device.forEachConnection("storage", StorageConnection::class.java) { connection ->
|
||||
try {
|
||||
val pl = loaderMap.computeIfAbsent(connection, loaderFactory)
|
||||
|
@ -6,10 +6,7 @@
|
||||
package inr.numass.control.readvac
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.control.devices.Device
|
||||
import hep.dataforge.control.devices.PortSensor
|
||||
import hep.dataforge.control.measurements.Measurement
|
||||
import hep.dataforge.control.measurements.SimpleMeasurement
|
||||
import hep.dataforge.control.ports.ComPort
|
||||
import hep.dataforge.control.ports.GenericPortController
|
||||
import hep.dataforge.control.ports.Port
|
||||
@ -31,51 +28,36 @@ class CM32Device(context: Context, meta: Meta) : PortSensor<Double>(context, met
|
||||
} else {
|
||||
PortFactory.build(meta)
|
||||
}
|
||||
return GenericPortController(context, port){it.endsWith("T--\r")}
|
||||
return GenericPortController(context, port) { it.endsWith("T--\r") }
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun startMeasurement(oldMeta: Meta, newMeta: Meta) {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) {
|
||||
startMeasurement {
|
||||
doMeasure()
|
||||
}
|
||||
}
|
||||
|
||||
override fun createMeasurement(): Measurement<Double> = CMVacMeasurement()
|
||||
private fun doMeasure(): Meta{
|
||||
val answer = sendAndWait("MES R PM 1\r\n")
|
||||
|
||||
return if (answer.isEmpty()) {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
produceError("No signal")
|
||||
} else if (!answer.contains("PM1:mbar")) {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
produceError("Wrong answer: $answer")
|
||||
} else if (answer.substring(14, 17) == "OFF") {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
produceError("Off")
|
||||
} else {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
produceResult(answer.substring(14, 17) + answer.substring(19, 23))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getType(): String {
|
||||
return getMeta().getString("type", "Leibold CM32")
|
||||
}
|
||||
|
||||
private inner class CMVacMeasurement : SimpleMeasurement<Double>() {
|
||||
|
||||
@Synchronized
|
||||
@Throws(Exception::class)
|
||||
override fun doMeasure(): Double? {
|
||||
|
||||
val answer = sendAndWait("MES R PM 1\r\n")
|
||||
|
||||
if (answer.isEmpty()) {
|
||||
this.updateMessage("No signal")
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
return null
|
||||
} else if (!answer.contains("PM1:mbar")) {
|
||||
this.updateMessage("Wrong answer: " + answer)
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
return null
|
||||
} else if (answer.substring(14, 17) == "OFF") {
|
||||
this.updateMessage("Off")
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
return null
|
||||
} else {
|
||||
this.updateMessage("OK")
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
return java.lang.Double.parseDouble(answer.substring(14, 17) + answer.substring(19, 23))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDevice(): Device = this@CM32Device
|
||||
|
||||
|
||||
return meta.getString("type", "numass.vac.cm32")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,14 +6,15 @@
|
||||
package inr.numass.control.readvac
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.control.devices.Device
|
||||
import hep.dataforge.control.devices.PortSensor
|
||||
import hep.dataforge.control.measurements.Measurement
|
||||
import hep.dataforge.control.measurements.SimpleMeasurement
|
||||
import hep.dataforge.control.devices.intState
|
||||
import hep.dataforge.control.ports.GenericPortController
|
||||
import hep.dataforge.control.ports.Port
|
||||
import hep.dataforge.control.ports.PortFactory
|
||||
import hep.dataforge.description.ValueDef
|
||||
import hep.dataforge.exceptions.ControlException
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.states.StateDef
|
||||
import hep.dataforge.values.ValueType
|
||||
import inr.numass.control.DeviceView
|
||||
|
||||
/**
|
||||
@ -21,52 +22,41 @@ import inr.numass.control.DeviceView
|
||||
*/
|
||||
@ValueDef(name = "channel")
|
||||
@DeviceView(VacDisplay::class)
|
||||
@StateDef(value = ValueDef(name = "channel", type = [ValueType.NUMBER], def = "2"), writable = true)
|
||||
class MKSBaratronDevice(context: Context, meta: Meta) : PortSensor<Double>(context, meta) {
|
||||
|
||||
private val channel: Int = getMeta().getInt("channel", 2)
|
||||
|
||||
|
||||
override fun createMeasurement(): Measurement<Double> = BaratronMeasurement()
|
||||
var channel by intState("channel")
|
||||
|
||||
override fun getType(): String {
|
||||
return getMeta().getString("type", "MKS baratron")
|
||||
return meta.getString("type", "numass.vac.baratron")
|
||||
}
|
||||
|
||||
@Throws(ControlException::class)
|
||||
override fun buildPort(portName: String): Port {
|
||||
val handler = super.buildPort(portName)
|
||||
handler.setDelimiter("\r")
|
||||
return handler
|
||||
override fun connect(meta: Meta): GenericPortController {
|
||||
val port: Port = PortFactory.build(meta)
|
||||
logger.info("Connecting to port {}", port.name)
|
||||
return GenericPortController(context, port) { it.endsWith("\r") }
|
||||
}
|
||||
|
||||
private inner class BaratronMeasurement : SimpleMeasurement<Double>() {
|
||||
|
||||
override fun getDevice(): Device {
|
||||
return this@MKSBaratronDevice
|
||||
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) {
|
||||
startMeasurement(newMeta) {
|
||||
doMeasure()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@Throws(Exception::class)
|
||||
override fun doMeasure(): Double? {
|
||||
val answer = sendAndWait("AV" + channel + "\r")
|
||||
if (answer == null || answer.isEmpty()) {
|
||||
// invalidateState("connection");
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
this.updateMessage("No connection")
|
||||
return null
|
||||
} else {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
}
|
||||
val res = java.lang.Double.parseDouble(answer)
|
||||
if (res <= 0) {
|
||||
this.updateMessage("Non positive")
|
||||
// invalidateState("power");
|
||||
return null
|
||||
} else {
|
||||
this.updateMessage("OK")
|
||||
return res
|
||||
}
|
||||
private fun doMeasure(): Meta {
|
||||
val answer = sendAndWait("AV$channel\r")
|
||||
if (answer.isEmpty()) {
|
||||
// invalidateState("connection");
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
return produceError("No connection")
|
||||
} else {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
}
|
||||
val res = java.lang.Double.parseDouble(answer)
|
||||
return if (res <= 0) {
|
||||
produceError("Non positive")
|
||||
} else {
|
||||
produceResult(res)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,11 @@
|
||||
package inr.numass.control.readvac
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.control.devices.Device
|
||||
import hep.dataforge.control.devices.PortSensor
|
||||
import hep.dataforge.control.measurements.Measurement
|
||||
import hep.dataforge.control.measurements.SimpleMeasurement
|
||||
import hep.dataforge.control.devices.booleanState
|
||||
import hep.dataforge.control.ports.GenericPortController
|
||||
import hep.dataforge.control.ports.Port
|
||||
import hep.dataforge.control.ports.PortFactory
|
||||
import hep.dataforge.description.ValueDef
|
||||
import hep.dataforge.description.ValueDefs
|
||||
import hep.dataforge.exceptions.ControlException
|
||||
@ -40,13 +40,7 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor<Double>(context, m
|
||||
|
||||
private val deviceAddress: String = meta.getString("address", "253")
|
||||
|
||||
|
||||
// val isPowerOnProperty = SimpleBooleanProperty()
|
||||
// var isPowerOn by isPowerOnProperty
|
||||
|
||||
|
||||
// val channelProperty = SimpleIntegerProperty(meta.getInt("channel", 5))
|
||||
// var channel by channelProperty
|
||||
var power: Boolean by booleanState("power")
|
||||
|
||||
|
||||
@Throws(ControlException::class)
|
||||
@ -61,15 +55,12 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor<Double>(context, m
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(ControlException::class)
|
||||
override fun buildPort(portName: String): Port {
|
||||
val handler = super.buildPort(portName)
|
||||
handler.setDelimiter(";FF")
|
||||
return handler
|
||||
override fun connect(meta: Meta): GenericPortController {
|
||||
val port: Port = PortFactory.build(meta)
|
||||
logger.info("Connecting to port {}", port.name)
|
||||
return GenericPortController(context, port) { it.endsWith(";FF") }
|
||||
}
|
||||
|
||||
override fun createMeasurement(): Measurement<Double> = MKSVacMeasurement()
|
||||
|
||||
@Throws(ControlException::class)
|
||||
override fun computeState(stateName: String): Any = when (stateName) {
|
||||
"power" -> talk("FP?") == "ON"
|
||||
@ -79,7 +70,7 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor<Double>(context, m
|
||||
@Throws(ControlException::class)
|
||||
override fun requestStateChange(stateName: String, value: Value) {
|
||||
when (stateName) {
|
||||
"power" -> setPower(value.booleanValue())
|
||||
"power" -> setPowerOn(value.booleanValue())
|
||||
else -> super.requestStateChange(stateName, value)
|
||||
}
|
||||
|
||||
@ -93,18 +84,8 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor<Double>(context, m
|
||||
super.shutdown()
|
||||
}
|
||||
|
||||
// fun powerOnProperty(): BooleanProperty {
|
||||
// try {
|
||||
// return JavaBeanBooleanPropertyBuilder().bean(this)
|
||||
// .name("powerOn").getter("isPowerOn").setter("setPower").build()
|
||||
// } catch (ex: NoSuchMethodException) {
|
||||
// throw Error(ex)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
private fun setPower(powerOn: Boolean) {
|
||||
if (powerOn != getLogicalState("power").booleanValue()) {
|
||||
private fun setPowerOn(powerOn: Boolean) {
|
||||
if (powerOn != power) {
|
||||
if (powerOn) {
|
||||
// String ans = talkMKS(p1Port, "@253ENC!OFF;FF");
|
||||
// if (!ans.equals("OFF")) {
|
||||
@ -112,47 +93,44 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor<Double>(context, m
|
||||
// }
|
||||
val ans = talk("FP!ON")
|
||||
if (ans == "ON") {
|
||||
setLogicalState("power", true)
|
||||
updateLogicalState("power", true)
|
||||
} else {
|
||||
this.notifyError("Failed to set power state", null)
|
||||
this.notifyError("Failed to set power state")
|
||||
}
|
||||
} else {
|
||||
val ans = talk("FP!OFF")
|
||||
if (ans == "OFF") {
|
||||
setLogicalState("power", false)
|
||||
updateLogicalState("power", false)
|
||||
} else {
|
||||
this.notifyError("Failed to set power state", null)
|
||||
this.notifyError("Failed to set power state")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getType(): String = meta.getString("type", "MKS vacuumeter")
|
||||
override fun getType(): String = meta.getString("type", "numass.vac.mks")
|
||||
|
||||
private inner class MKSVacMeasurement : SimpleMeasurement<Double>() {
|
||||
|
||||
@Synchronized
|
||||
@Throws(Exception::class)
|
||||
override fun doMeasure(): Double? {
|
||||
// if (getState("power").booleanValue()) {
|
||||
val channel = meta.getInt("channel", 5)
|
||||
val answer = talk("PR$channel?")
|
||||
if (answer == null || answer.isEmpty()) {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
this.updateMessage("No connection")
|
||||
return null
|
||||
}
|
||||
val res = parseDouble(answer)
|
||||
return if (res <= 0) {
|
||||
this.updateMessage("No power")
|
||||
updateLogicalState("power", false)
|
||||
null
|
||||
} else {
|
||||
this.updateMessage("OK")
|
||||
res
|
||||
}
|
||||
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) {
|
||||
startMeasurement(newMeta) {
|
||||
doMeasure()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDevice(): Device = this@MKSVacDevice
|
||||
private fun doMeasure(): Meta {
|
||||
// if (getState("power").booleanValue()) {
|
||||
val channel = meta.getInt("channel", 5)
|
||||
val answer = talk("PR$channel?")
|
||||
if (answer == null || answer.isEmpty()) {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
return produceError("No connection")
|
||||
}
|
||||
val res = parseDouble(answer)
|
||||
return if (res <= 0) {
|
||||
updateLogicalState("power", false)
|
||||
produceError("No power")
|
||||
} else {
|
||||
this.updateMessage("OK")
|
||||
produceResult(res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,14 @@
|
||||
package inr.numass.control.readvac
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.control.devices.Device
|
||||
import hep.dataforge.control.devices.PortSensor
|
||||
import hep.dataforge.control.measurements.Measurement
|
||||
import hep.dataforge.control.measurements.SimpleMeasurement
|
||||
import hep.dataforge.control.devices.intState
|
||||
import hep.dataforge.control.ports.GenericPortController
|
||||
import hep.dataforge.control.ports.Port
|
||||
import hep.dataforge.control.ports.PortFactory
|
||||
import hep.dataforge.description.ValueDef
|
||||
import hep.dataforge.exceptions.ControlException
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.states.StateDef
|
||||
import hep.dataforge.values.ValueType.NUMBER
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
@ -23,73 +23,63 @@ import java.util.regex.Pattern
|
||||
/**
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
@ValueDef(name = "address", type = arrayOf(NUMBER), def = "1", info = "A modbus address")
|
||||
@StateDef(value = ValueDef(name = "address", type = [NUMBER], def = "1", info = "A modbus address"), writable = true)
|
||||
class MeradatVacDevice(context: Context, meta: Meta) : PortSensor<Double>(context, meta) {
|
||||
|
||||
@Throws(ControlException::class)
|
||||
override fun buildPort(portName: String): Port {
|
||||
val newHandler = super.buildPort(portName)
|
||||
newHandler.setDelimiter("\r\n")
|
||||
return newHandler
|
||||
}
|
||||
var address by intState("address")
|
||||
|
||||
override fun createMeasurement(): Measurement<Double> = MeradatMeasurement()
|
||||
override fun connect(meta: Meta): GenericPortController {
|
||||
val port: Port = PortFactory.build(meta)
|
||||
logger.info("Connecting to port {}", port.name)
|
||||
|
||||
return GenericPortController(context, port) { it.endsWith("\r\n") }
|
||||
}
|
||||
|
||||
override fun getType(): String {
|
||||
return getMeta().getString("type", "Vit vacuumeter")
|
||||
return meta.getString("type", "numass.vac.vit")
|
||||
}
|
||||
|
||||
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) {
|
||||
startMeasurement(newMeta) {
|
||||
doMeasure()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private inner class MeradatMeasurement : SimpleMeasurement<Double>() {
|
||||
private fun doMeasure(): Meta {
|
||||
val requestBase: String = String.format(":%02d", address)
|
||||
val dataStr = requestBase.substring(1) + REQUEST
|
||||
val query = requestBase + REQUEST + calculateLRC(dataStr) + "\r\n" // ":010300000002FA\r\n";
|
||||
val response: Pattern = Pattern.compile(requestBase + "0304(\\w{4})(\\w{4})..\r\n")
|
||||
|
||||
private val query: String // ":010300000002FA\r\n";
|
||||
private val response: Pattern
|
||||
private val base: String
|
||||
val answer = sendAndWait(query) { phrase -> phrase.startsWith(requestBase) }
|
||||
|
||||
init {
|
||||
base = String.format(":%02d", getMeta().getInt("address", 1))
|
||||
val dataStr = base.substring(1) + REQUEST
|
||||
query = base + REQUEST + calculateLRC(dataStr) + "\r\n"
|
||||
response = Pattern.compile(base + "0304(\\w{4})(\\w{4})..\r\n")
|
||||
}
|
||||
if (answer.isEmpty()) {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
return produceError("No signal")
|
||||
} else {
|
||||
val match = response.matcher(answer)
|
||||
|
||||
@Synchronized
|
||||
@Throws(Exception::class)
|
||||
override fun doMeasure(): Double? {
|
||||
|
||||
val answer = sendAndWait(query) { phrase -> phrase.startsWith(base) }
|
||||
|
||||
if (answer.isEmpty()) {
|
||||
this.updateMessage("No signal")
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
return null
|
||||
} else {
|
||||
val match = response.matcher(answer)
|
||||
|
||||
if (match.matches()) {
|
||||
val base = Integer.parseInt(match.group(1), 16).toDouble() / 10.0
|
||||
var exp = Integer.parseInt(match.group(2), 16)
|
||||
if (exp > 32766) {
|
||||
exp -= 65536
|
||||
}
|
||||
var res = BigDecimal.valueOf(base * Math.pow(10.0, exp.toDouble()))
|
||||
res = res.setScale(4, RoundingMode.CEILING)
|
||||
this.updateMessage("OK")
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
return res.toDouble()
|
||||
} else {
|
||||
this.updateMessage("Wrong answer: " + answer)
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
return null
|
||||
return if (match.matches()) {
|
||||
val base = Integer.parseInt(match.group(1), 16).toDouble() / 10.0
|
||||
var exp = Integer.parseInt(match.group(2), 16)
|
||||
if (exp > 32766) {
|
||||
exp -= 65536
|
||||
}
|
||||
var res = BigDecimal.valueOf(base * Math.pow(10.0, exp.toDouble()))
|
||||
res = res.setScale(4, RoundingMode.CEILING)
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, true)
|
||||
produceResult(res)
|
||||
} else {
|
||||
updateLogicalState(PortSensor.CONNECTED_STATE, false)
|
||||
produceError("Wrong answer: $answer")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDevice(): Device = this@MeradatVacDevice
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private val REQUEST = "0300000002"
|
||||
private const val REQUEST = "0300000002"
|
||||
|
||||
fun calculateLRC(inputString: String): String {
|
||||
/*
|
||||
@ -100,7 +90,7 @@ class MeradatVacDevice(context: Context, meta: Meta) : PortSensor<Double>(contex
|
||||
var value = Integer.toHexString(-checksum)
|
||||
value = value.substring(value.length - 2).toUpperCase()
|
||||
if (value.length < 2) {
|
||||
value = "0" + value
|
||||
value = "0$value"
|
||||
}
|
||||
|
||||
return value
|
||||
|
@ -12,9 +12,9 @@ import hep.dataforge.control.collectors.RegularPointCollector
|
||||
import hep.dataforge.control.connections.Roles
|
||||
import hep.dataforge.control.devices.Device
|
||||
import hep.dataforge.control.devices.DeviceHub
|
||||
import hep.dataforge.control.devices.DeviceListener
|
||||
import hep.dataforge.control.devices.PortSensor.Companion.CONNECTED_STATE
|
||||
import hep.dataforge.control.devices.Sensor
|
||||
import hep.dataforge.control.measurements.AbstractMeasurement
|
||||
import hep.dataforge.control.measurements.Measurement
|
||||
import hep.dataforge.description.ValueDef
|
||||
import hep.dataforge.exceptions.ControlException
|
||||
import hep.dataforge.meta.Meta
|
||||
@ -31,13 +31,10 @@ import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.Values
|
||||
import inr.numass.control.DeviceView
|
||||
import inr.numass.control.StorageHelper
|
||||
import kotlinx.coroutines.experimental.launch
|
||||
import kotlinx.coroutines.experimental.time.delay
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.ScheduledExecutorService
|
||||
import java.util.concurrent.ScheduledFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.stream.Stream
|
||||
|
||||
/**
|
||||
@ -50,8 +47,22 @@ class VacCollectorDevice(context: Context, meta: Meta, val sensors: Collection<S
|
||||
|
||||
private val helper = StorageHelper(this, this::buildLoader)
|
||||
|
||||
private val averagingDuration: Duration
|
||||
get() = Duration.parse(getMeta().getString("averagingDuration", "PT30S"))
|
||||
private val collector = object : DeviceListener {
|
||||
val averagingDuration: Duration = Duration.parse(meta.getString("averagingDuration", "PT30S"))
|
||||
private val collector = RegularPointCollector(averagingDuration) {
|
||||
notifyResult(it)
|
||||
}
|
||||
|
||||
override fun notifyDeviceStateChanged(device: Device, name: String, state: Value) {
|
||||
|
||||
}
|
||||
|
||||
override fun notifyDeviceStateChanged(device: Device, name: String, state: Meta) {
|
||||
if (name == MEASUREMENT_RESULT_STATE) {
|
||||
collector.put(device.name, state.getValue("value"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun optDevice(name: Name): Optional<Device> =
|
||||
@ -66,8 +77,6 @@ class VacCollectorDevice(context: Context, meta: Meta, val sensors: Collection<S
|
||||
s.init()
|
||||
}
|
||||
}
|
||||
//TODO use meta
|
||||
override fun createMeasurement(): Measurement<Values> = VacuumMeasurement()
|
||||
|
||||
override fun getType(): String = "numass.vac.collector"
|
||||
|
||||
@ -87,7 +96,7 @@ class VacCollectorDevice(context: Context, meta: Meta, val sensors: Collection<S
|
||||
|
||||
val suffix = DateTimeUtils.fileSuffix()
|
||||
|
||||
return LoaderFactory.buildPointLoader(connection.storage, "vactms_" + suffix, "", "timestamp", format.build())
|
||||
return LoaderFactory.buildPointLoader(connection.storage, "vactms_$suffix", "", "timestamp", format.build())
|
||||
}
|
||||
|
||||
override fun connectAll(connection: Connection, vararg roles: String) {
|
||||
@ -100,61 +109,46 @@ class VacCollectorDevice(context: Context, meta: Meta, val sensors: Collection<S
|
||||
this.sensors.forEach { it.connectionHelper.connect(context, meta) }
|
||||
}
|
||||
|
||||
private inner class VacuumMeasurement : AbstractMeasurement<Values>() {
|
||||
|
||||
private val collector = RegularPointCollector(averagingDuration) { this.result(it) }
|
||||
private var executor: ScheduledExecutorService? = null
|
||||
private var currentTask: ScheduledFuture<*>? = null
|
||||
private fun notifyResult(values: Values) {
|
||||
notifyResult(produceResult(values.toMeta()))
|
||||
helper.push(values)
|
||||
}
|
||||
|
||||
override fun getDevice(): Device {
|
||||
return this@VacCollectorDevice
|
||||
}
|
||||
|
||||
|
||||
override fun start() {
|
||||
executor = Executors.newSingleThreadScheduledExecutor { r: Runnable -> Thread(r, "VacuumMeasurement thread") }
|
||||
val delay = getMeta().getInt("delay", 5)!! * 1000
|
||||
currentTask = executor!!.scheduleWithFixedDelay({
|
||||
sensors.forEach { sensor ->
|
||||
try {
|
||||
val value: Any?
|
||||
value = if (sensor.optBooleanState(CONNECTED_STATE).orElse(false)) {
|
||||
sensor.read()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
collector.put(sensor.name, value)
|
||||
} catch (ex: Exception) {
|
||||
collector.put(sensor.name, Value.NULL)
|
||||
}
|
||||
}
|
||||
}, 0, delay.toLong(), TimeUnit.MILLISECONDS)
|
||||
}
|
||||
|
||||
|
||||
@Synchronized override fun result(result: Values, time: Instant) {
|
||||
super.result(result, time)
|
||||
helper.push(result)
|
||||
}
|
||||
|
||||
private fun terminator(): Values {
|
||||
val p = ValueMap.Builder()
|
||||
p.putValue("timestamp", DateTimeUtils.now())
|
||||
getDeviceNames().forEach { n -> p.putValue(n.toUnescaped(), null) }
|
||||
return p.build()
|
||||
}
|
||||
|
||||
override fun stop(force: Boolean): Boolean {
|
||||
val isRunning = currentTask != null
|
||||
if (isRunning) {
|
||||
logger.debug("Stopping vacuum collector measurement. Writing terminator point")
|
||||
result(terminator())
|
||||
currentTask!!.cancel(force)
|
||||
executor!!.shutdown()
|
||||
currentTask = null
|
||||
afterStop()
|
||||
override fun onStateChange(stateName: String, oldState: Value?, newState: Value) {
|
||||
if (stateName == MEASURING_STATE) {
|
||||
if (!newState.booleanValue()) {
|
||||
notifyResult(terminator())
|
||||
}
|
||||
return isRunning
|
||||
}
|
||||
}
|
||||
|
||||
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) {
|
||||
oldMeta?.let {
|
||||
stopMeasurement()
|
||||
}
|
||||
|
||||
val interval = Duration.ofSeconds(meta.getInt("delay", 5).toLong())
|
||||
|
||||
job = launch {
|
||||
while (true) {
|
||||
notifyMeasurementState(MeasurementState.IN_PROGRESS)
|
||||
sensors.forEach { sensor ->
|
||||
if (sensor.optBooleanState(CONNECTED_STATE).orElse(false)) {
|
||||
sensor.measure()
|
||||
}
|
||||
}
|
||||
notifyMeasurementState(MeasurementState.WAITING)
|
||||
delay(interval)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun terminator(): Values {
|
||||
val p = ValueMap.Builder()
|
||||
deviceNames.forEach { n -> p.putValue(n.toUnescaped(), null) }
|
||||
return p.build()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user