From a12ee234f90a86309c8dee173d6290a62cf6e85f Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 26 Nov 2018 13:07:12 +0300 Subject: [PATCH] Minor changes to devices --- .../inr/numass/control/cryotemp/PKT8Device.kt | 1 + numass-control/gun/build.gradle | 28 ++++ .../inr/numass/control/gun/IT6800Device.kt | 145 ++++++++++++++++++ settings.gradle | 1 + 4 files changed, 175 insertions(+) create mode 100644 numass-control/gun/build.gradle create mode 100644 numass-control/gun/src/main/kotlin/inr/numass/control/gun/IT6800Device.kt diff --git a/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8Device.kt b/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8Device.kt index 6854e51e..8c51db90 100644 --- a/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8Device.kt +++ b/numass-control/cryotemp/src/main/kotlin/inr/numass/control/cryotemp/PKT8Device.kt @@ -22,6 +22,7 @@ import hep.dataforge.control.collectors.RegularPointCollector import hep.dataforge.control.connections.Roles import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.Sensor +import hep.dataforge.control.devices.notifyError import hep.dataforge.control.ports.GenericPortController import hep.dataforge.control.ports.Port import hep.dataforge.control.ports.PortFactory diff --git a/numass-control/gun/build.gradle b/numass-control/gun/build.gradle new file mode 100644 index 00000000..46e88a86 --- /dev/null +++ b/numass-control/gun/build.gradle @@ -0,0 +1,28 @@ +/* + * Copyright 2018 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. + */ + +apply plugin: 'application' + +version = "0.1.0" + +if (!hasProperty('mainClass')) { + ext.mainClass = 'inr.numass.control.magnet.fx.MagnetApp' +} +mainClassName = mainClass + +dependencies { + compile project(':numass-control') +} \ No newline at end of file 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 new file mode 100644 index 00000000..7db8b40b --- /dev/null +++ b/numass-control/gun/src/main/kotlin/inr/numass/control/gun/IT6800Device.kt @@ -0,0 +1,145 @@ +/* + * Copyright 2018 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.control.gun + +import hep.dataforge.context.Context +import hep.dataforge.control.devices.AbstractDevice +import hep.dataforge.control.ports.PortHelper +import hep.dataforge.meta.Meta +import hep.dataforge.states.valueState +import tornadofx.* +import java.nio.ByteBuffer +import java.nio.ByteOrder +import kotlin.experimental.and + + +class IT6800Device(context: Context, meta: Meta) : AbstractDevice(context, meta) { + private val portHelper = PortHelper(this) + + val connected get() = portHelper.connected + + val address: Byte = meta.getValue("address", 0).number.toByte() + + val remoteState = valueState("remote", + setter = { value -> sendBoolean(Command.REMOTE.code, value.boolean) } + ) + + val outputState = valueState("output", + setter = { value -> sendBoolean(Command.OUTPUT.code, value.boolean) } + ) + + val voltageState = valueState("voltage", + setter = { value -> sendInt(Command.VOLTAGE.code, (value.double * 1000).toInt()) } + ) + + val currentState = valueState("current", + setter = { value -> sendShort(Command.CURRENT.code, (value.double * 1000).toInt().toShort()) } + ) + + fun connect() { + connected.set(true) + portHelper.connection.onAnyPhrase(this) { + val buffer = ByteBuffer.wrap(it.toByteArray(Charsets.US_ASCII)) + buffer.order(ByteOrder.LITTLE_ENDIAN) + + if (buffer.get(1) != address) { + //skip + return@onAnyPhrase + } + + val code = buffer.get(2) + when (code) { + Command.REMOTE.code -> { + val value = buffer[3] > 0 + remoteState.update(value) + } + Command.OUTPUT.code -> { + val value = buffer[3] > 0 + outputState.update(value) + } + Command.VOLTAGE.code -> { + val value = buffer.getInt(3) + voltageState.update(value.toDouble() / 1000) + } + Command.CURRENT.code -> { + val value = buffer.getShort(3) + currentState.update(value.toDouble() / 1000) + } + Command.READ.code -> { + val current = buffer.getShort(3) + currentState.update(current.toDouble() / 1000) + val value = buffer.getInt(5) + 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) + } + } + } + } + + private fun request(command: Byte, data: ByteBuffer): String { + if (data.limit() != 21) error("Wrong size of data array") + val buffer = ByteBuffer.allocate(26) + buffer.put(0, START) + buffer.put(1, address) + buffer.put(2, command) + buffer.position(3) + buffer.put(data) + val checksum = (START + address + command + data.array().sum()).rem(256).toByte() + buffer.put(25, checksum) + return String(buffer.array(), Charsets.US_ASCII) + } + + private fun sendBoolean(command: Byte, value: Boolean) { + val data = ByteBuffer.allocate(21) + data.put(0, if (value) 1 else 0) + portHelper.send(request(command, data)) + } + + private fun sendShort(command: Byte, value: Short) { + val data = ByteBuffer.allocate(21) + data.order(ByteOrder.LITTLE_ENDIAN) + data.putShort(0, value) + portHelper.send(request(command, data)) + } + + private fun sendInt(command: Byte, value: Int) { + val data = ByteBuffer.allocate(21) + data.order(ByteOrder.LITTLE_ENDIAN) + data.putInt(0, value) + portHelper.send(request(command, data)) + } + + override fun shutdown() { + portHelper.shutdown() + super.shutdown() + } + + enum class Command(val code: Byte) { + REMOTE(0x20), + OUTPUT(0x21), + VOLTAGE(0x23), + CURRENT(0x24), + READ(0x26), + INFO(0x31) + } + + companion object { + private const val START = (170).toByte() // AA + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 741bb52d..bbd2f6a1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,7 @@ include ":numass-control:msp" include ":numass-control:vac" //include ":numass-control:control-room" include ":numass-control:dante" +include ":numass-control:gun" // include ":numass-main" //