From 69617e73b40bd7e959346fa9276c4e16f38ad79c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 16 Aug 2023 10:37:02 +0300 Subject: [PATCH] Replace JSSC with JSerialComm --- .../kscience/controls/ports/ChannelPort.kt | 4 +- controls-serial/build.gradle.kts | 2 +- .../controls/serial/JSerialCommPort.kt | 87 +++++++++++++++++ .../kscience/controls/serial/SerialPort.kt | 93 ------------------- .../controls/serial/SerialPortPlugin.kt | 2 +- magix/build.gradle.kts | 3 - .../space/kscience/magix/api/MagixEndpoint.kt | 8 +- .../{connections => services}/magixPortal.kt | 2 +- magix/rfc | 2 +- 9 files changed, 97 insertions(+), 106 deletions(-) create mode 100644 controls-serial/src/main/kotlin/space/kscience/controls/serial/JSerialCommPort.kt delete mode 100644 controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPort.kt rename magix/magix-api/src/commonMain/kotlin/space/kscience/magix/{connections => services}/magixPortal.kt (96%) diff --git a/controls-core/src/jvmMain/kotlin/space/kscience/controls/ports/ChannelPort.kt b/controls-core/src/jvmMain/kotlin/space/kscience/controls/ports/ChannelPort.kt index d7983f2..23a57da 100644 --- a/controls-core/src/jvmMain/kotlin/space/kscience/controls/ports/ChannelPort.kt +++ b/controls-core/src/jvmMain/kotlin/space/kscience/controls/ports/ChannelPort.kt @@ -73,7 +73,7 @@ public class ChannelPort( } /** - * A [PortFactory] for TCP connections + * A [PortFactory] for TCP services */ public object TcpPort : PortFactory { @@ -97,7 +97,7 @@ public object TcpPort : PortFactory { /** - * A [PortFactory] for UDP connections + * A [PortFactory] for UDP services */ public object UdpPort : PortFactory { diff --git a/controls-serial/build.gradle.kts b/controls-serial/build.gradle.kts index b28a210..006a7c2 100644 --- a/controls-serial/build.gradle.kts +++ b/controls-serial/build.gradle.kts @@ -5,5 +5,5 @@ plugins { dependencies{ api(project(":controls-core")) - implementation("org.scream3r:jssc:2.8.0") + implementation("com.fazecast:jSerialComm:2.10.3") } \ No newline at end of file diff --git a/controls-serial/src/main/kotlin/space/kscience/controls/serial/JSerialCommPort.kt b/controls-serial/src/main/kotlin/space/kscience/controls/serial/JSerialCommPort.kt new file mode 100644 index 0000000..3e0601c --- /dev/null +++ b/controls-serial/src/main/kotlin/space/kscience/controls/serial/JSerialCommPort.kt @@ -0,0 +1,87 @@ +package space.kscience.controls.serial + +import com.fazecast.jSerialComm.SerialPort +import com.fazecast.jSerialComm.SerialPortDataListener +import com.fazecast.jSerialComm.SerialPortEvent +import kotlinx.coroutines.launch +import space.kscience.controls.ports.AbstractPort +import space.kscience.controls.ports.Port +import space.kscience.controls.ports.PortFactory +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.string +import kotlin.coroutines.CoroutineContext + +/** + * A port based on JSerialComm + */ +public class JSerialCommPort( + context: Context, + private val comPort: SerialPort, + coroutineContext: CoroutineContext = context.coroutineContext, +) : AbstractPort(context, coroutineContext) { + + override fun toString(): String = "port[${comPort.descriptivePortName}]" + + private val serialPortListener = object : SerialPortDataListener { + override fun getListeningEvents(): Int = SerialPort.LISTENING_EVENT_DATA_AVAILABLE + + override fun serialEvent(event: SerialPortEvent) { + if (event.eventType == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) { + scope.launch { receive(event.receivedData) } + } + } + } + + init { + comPort.addDataListener(serialPortListener) + } + + override suspend fun write(data: ByteArray) { + comPort.writeBytes(data, data.size) + } + + override fun close() { + comPort.removeDataListener() + if (comPort.isOpen) { + comPort.closePort() + } + super.close() + } + + public companion object : PortFactory { + + override val type: String = "com" + + + /** + * Construct ComPort with given parameters + */ + public fun open( + context: Context, + portName: String, + baudRate: Int = 9600, + dataBits: Int = 8, + stopBits: Int = SerialPort.ONE_STOP_BIT, + parity: Int = SerialPort.NO_PARITY, + coroutineContext: CoroutineContext = context.coroutineContext, + ): JSerialCommPort { + val serialPort = SerialPort.getCommPort(portName).apply { + setComPortParameters(baudRate, dataBits, stopBits, parity) + openPort() + } + return JSerialCommPort(context, serialPort, coroutineContext) + } + + override fun build(context: Context, meta: Meta): Port { + val name by meta.string { error("Serial port name not defined") } + val baudRate by meta.int(9600) + val dataBits by meta.int(8) + val stopBits by meta.int(SerialPort.ONE_STOP_BIT) + val parity by meta.int(SerialPort.NO_PARITY) + return open(context, name, baudRate, dataBits, stopBits, parity) + } + } + +} \ No newline at end of file diff --git a/controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPort.kt b/controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPort.kt deleted file mode 100644 index 54b7ac8..0000000 --- a/controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPort.kt +++ /dev/null @@ -1,93 +0,0 @@ -package space.kscience.controls.serial - -import jssc.SerialPort.* -import jssc.SerialPortEventListener -import kotlinx.coroutines.launch -import space.kscience.controls.ports.AbstractPort -import space.kscience.controls.ports.Port -import space.kscience.controls.ports.PortFactory -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.meta.string -import kotlin.coroutines.CoroutineContext -import jssc.SerialPort as JSSCPort - -/** - * COM/USB port - */ -public class SerialPort private constructor( - context: Context, - private val jssc: JSSCPort, - coroutineContext: CoroutineContext = context.coroutineContext, -) : AbstractPort(context, coroutineContext) { - - override fun toString(): String = "port[${jssc.portName}]" - - private val serialPortListener = SerialPortEventListener { event -> - if (event.isRXCHAR) { - val chars = event.eventValue - val bytes = jssc.readBytes(chars) - scope.launch { receive(bytes) } - } - } - - init { - jssc.addEventListener(serialPortListener) - } - - /** - * Clear current input and output buffers - */ - internal fun clearPort() { - jssc.purgePort(PURGE_RXCLEAR or PURGE_TXCLEAR) - } - - override suspend fun write(data: ByteArray) { - jssc.writeBytes(data) - } - - @Throws(Exception::class) - override fun close() { - jssc.removeEventListener() - clearPort() - if (jssc.isOpened) { - jssc.closePort() - } - super.close() - } - - public companion object : PortFactory { - - override val type: String = "com" - - - /** - * Construct ComPort with given parameters - */ - public fun open( - context: Context, - portName: String, - baudRate: Int = BAUDRATE_9600, - dataBits: Int = DATABITS_8, - stopBits: Int = STOPBITS_1, - parity: Int = PARITY_NONE, - coroutineContext: CoroutineContext = context.coroutineContext, - ): SerialPort { - val jssc = JSSCPort(portName).apply { - openPort() - setParams(baudRate, dataBits, stopBits, parity) - } - return SerialPort(context, jssc, coroutineContext) - } - - override fun build(context: Context, meta: Meta): Port { - val name by meta.string { error("Serial port name not defined") } - val baudRate by meta.int(BAUDRATE_9600) - val dataBits by meta.int(DATABITS_8) - val stopBits by meta.int(STOPBITS_1) - val parity by meta.int(PARITY_NONE) - return open(context, name, baudRate, dataBits, stopBits, parity) - } - } -} \ No newline at end of file diff --git a/controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPortPlugin.kt b/controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPortPlugin.kt index 6b573ae..ae9d4fc 100644 --- a/controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPortPlugin.kt +++ b/controls-serial/src/main/kotlin/space/kscience/controls/serial/SerialPortPlugin.kt @@ -13,7 +13,7 @@ public class SerialPortPlugin : AbstractPlugin() { override val tag: PluginTag get() = Companion.tag override fun content(target: String): Map = when(target){ - PortFactory.TYPE -> mapOf(Name.EMPTY to SerialPort) + PortFactory.TYPE -> mapOf(Name.EMPTY to JSerialCommPort) else -> emptyMap() } diff --git a/magix/build.gradle.kts b/magix/build.gradle.kts index ae31ca2..e69de29 100644 --- a/magix/build.gradle.kts +++ b/magix/build.gradle.kts @@ -1,3 +0,0 @@ -subprojects{ - -} \ No newline at end of file diff --git a/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/api/MagixEndpoint.kt b/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/api/MagixEndpoint.kt index 35cb8e5..7658cd9 100644 --- a/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/api/MagixEndpoint.kt +++ b/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/api/MagixEndpoint.kt @@ -28,22 +28,22 @@ public interface MagixEndpoint { public companion object { /** - * A default port for HTTP/WS connections + * A default port for HTTP/WS services */ public const val DEFAULT_MAGIX_HTTP_PORT: Int = 7777 /** - * A default port for raw TCP connections + * A default port for raw TCP services */ public const val DEFAULT_MAGIX_RAW_PORT: Int = 7778 /** - * A default PUB port for ZMQ connections + * A default PUB port for ZMQ services */ public const val DEFAULT_MAGIX_ZMQ_PUB_PORT: Int = 7781 /** - * A default PULL port for ZMQ connections + * A default PULL port for ZMQ services */ public const val DEFAULT_MAGIX_ZMQ_PULL_PORT: Int = 7782 diff --git a/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/connections/magixPortal.kt b/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/services/magixPortal.kt similarity index 96% rename from magix/magix-api/src/commonMain/kotlin/space/kscience/magix/connections/magixPortal.kt rename to magix/magix-api/src/commonMain/kotlin/space/kscience/magix/services/magixPortal.kt index 9ede63f..d9ed009 100644 --- a/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/connections/magixPortal.kt +++ b/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/services/magixPortal.kt @@ -1,4 +1,4 @@ -package space.kscience.magix.connections +package space.kscience.magix.services import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job diff --git a/magix/rfc b/magix/rfc index 5ae42aa..7f50062 160000 --- a/magix/rfc +++ b/magix/rfc @@ -1 +1 @@ -Subproject commit 5ae42aa297fbd2ab2239601f064e1d1239487590 +Subproject commit 7f50062bd42dd5046110326cae2492ad1f7a195f