diff --git a/numass-control/gun/src/main/kotlin/inr/numass/control/gun/IT6800Device.kt b/numass-control/gun/src/main/kotlin/inr/numass/control/gun/IT6800Device.kt index 7db8b40b..4422c4e1 100644 --- a/numass-control/gun/src/main/kotlin/inr/numass/control/gun/IT6800Device.kt +++ b/numass-control/gun/src/main/kotlin/inr/numass/control/gun/IT6800Device.kt @@ -17,19 +17,27 @@ package inr.numass.control.gun import hep.dataforge.context.Context +import hep.dataforge.context.launch import hep.dataforge.control.devices.AbstractDevice import hep.dataforge.control.ports.PortHelper import hep.dataforge.meta.Meta +import hep.dataforge.nullable import hep.dataforge.states.valueState +import hep.dataforge.values.ValueType +import kotlinx.coroutines.Job +import kotlinx.coroutines.time.delay import tornadofx.* import java.nio.ByteBuffer import java.nio.ByteOrder +import java.time.Duration import kotlin.experimental.and class IT6800Device(context: Context, meta: Meta) : AbstractDevice(context, meta) { private val portHelper = PortHelper(this) + private var monitorJob: Job? = null + val connected get() = portHelper.connected val address: Byte = meta.getValue("address", 0).number.toByte() @@ -46,12 +54,17 @@ class IT6800Device(context: Context, meta: Meta) : AbstractDevice(context, meta) setter = { value -> sendInt(Command.VOLTAGE.code, (value.double * 1000).toInt()) } ) + val voltage by voltageState.doubleDelegate + val currentState = valueState("current", setter = { value -> sendShort(Command.CURRENT.code, (value.double * 1000).toInt().toShort()) } ) + val current by currentState.doubleDelegate + fun connect() { connected.set(true) + remoteState.set(true) portHelper.connection.onAnyPhrase(this) { val buffer = ByteBuffer.wrap(it.toByteArray(Charsets.US_ASCII)) buffer.order(ByteOrder.LITTLE_ENDIAN) @@ -86,12 +99,17 @@ class IT6800Device(context: Context, meta: Meta) : AbstractDevice(context, meta) voltageState.update(value.toDouble() / 1000) val state = buffer.get(9) outputState.update(state and 1 > 0) - remoteState.update(state.toInt() ushr 7 and 1 >0) + remoteState.update(state.toInt() ushr 7 and 1 > 0) } } } } + override fun init() { + super.init() + connect() + } + private fun request(command: Byte, data: ByteBuffer): String { if (data.limit() != 21) error("Wrong size of data array") val buffer = ByteBuffer.allocate(26) @@ -127,9 +145,41 @@ class IT6800Device(context: Context, meta: Meta) : AbstractDevice(context, meta) override fun shutdown() { portHelper.shutdown() + stopMonitor() super.shutdown() } + /** + * send update request + */ + fun update() { + portHelper.send(request(Command.READ.code, ByteBuffer.allocate(21))) + } + + /** + * Start regular state check + */ + fun startMonitor() { + val interval: Duration = meta.optValue("monitor.interval").nullable?.let { + if (it.type == ValueType.STRING) { + Duration.parse(it.string) + } else { + Duration.ofMillis(it.long) + } + } ?: Duration.ofMinutes(1) + + monitorJob = launch { + while (true) { + update() + delay(interval) + } + } + } + + fun stopMonitor() { + monitorJob?.cancel() + } + enum class Command(val code: Byte) { REMOTE(0x20), OUTPUT(0x21),