diff --git a/README.md b/README.md index f8746e0..f5ff350 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Generally, a Device has Properties that can be read and written. Also, some Acti can optionally be applied on a device (may or may not affect properties). - `base` - contains baseline `Device` implementation -[`DeviceBase`](dataforge-device-core/src/commonMain/kotlin/hep/dataforge/control/base/DeviceBase.kt) +[`DeviceBase`](controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceBase.kt) and property implementation, including property asynchronous flows. - `controllers` - implements Message Controller that can be attached to the event bus, Message diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Device.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Device.kt index 335e68c..1d8a8bb 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Device.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Device.kt @@ -1,11 +1,11 @@ -package space.kscience.dataforge.control.api +package ru.mipt.npm.controls.api import io.ktor.utils.io.core.Closeable import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.SharedFlow +import ru.mipt.npm.controls.api.Device.Companion.DEVICE_TARGET import space.kscience.dataforge.context.ContextAware -import space.kscience.dataforge.control.api.Device.Companion.DEVICE_TARGET import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaItem import space.kscience.dataforge.misc.Type diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/DeviceHub.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/DeviceHub.kt index a3fba5c..065c1b7 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/DeviceHub.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/DeviceHub.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.api +package ru.mipt.npm.controls.api import space.kscience.dataforge.meta.MetaItem import space.kscience.dataforge.names.* @@ -38,9 +38,7 @@ public interface DeviceHub : Provider { } } - public companion object { - - } + public companion object } public operator fun DeviceHub.get(nameToken: NameToken): Device = diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/messages/DeviceMessage.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/DeviceMessage.kt similarity index 99% rename from controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/messages/DeviceMessage.kt rename to controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/DeviceMessage.kt index 7145031..30df291 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/messages/DeviceMessage.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/DeviceMessage.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.messages +package ru.mipt.npm.controls.api import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Socket.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Socket.kt index 2d07d44..eda8942 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Socket.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/Socket.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.api +package ru.mipt.npm.controls.api import io.ktor.utils.io.core.Closeable import kotlinx.coroutines.CoroutineScope diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/descriptors.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/descriptors.kt index 0ab24cd..d7013e2 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/descriptors.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/api/descriptors.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.api +package ru.mipt.npm.controls.api import space.kscience.dataforge.meta.Scheme import space.kscience.dataforge.meta.string diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceAction.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceAction.kt index 979a593..eda0422 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceAction.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceAction.kt @@ -1,6 +1,6 @@ -package space.kscience.dataforge.control.base +package ru.mipt.npm.controls.base -import space.kscience.dataforge.control.api.ActionDescriptor +import ru.mipt.npm.controls.api.ActionDescriptor import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaItem import space.kscience.dataforge.meta.asMetaItem diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceBase.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceBase.kt index 047521c..8eb07a0 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceBase.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceBase.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.base +package ru.mipt.npm.controls.base import kotlinx.coroutines.* import kotlinx.coroutines.flow.MutableSharedFlow @@ -7,10 +7,10 @@ import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import ru.mipt.npm.controls.api.ActionDescriptor +import ru.mipt.npm.controls.api.Device +import ru.mipt.npm.controls.api.PropertyDescriptor import space.kscience.dataforge.context.Context -import space.kscience.dataforge.control.api.ActionDescriptor -import space.kscience.dataforge.control.api.Device -import space.kscience.dataforge.control.api.PropertyDescriptor import space.kscience.dataforge.meta.MetaItem import space.kscience.dataforge.misc.DFExperimental @@ -56,7 +56,7 @@ public abstract class DeviceBase(override val context: Context) : Device { override val actionDescriptors: Collection get() = _actions.values.map { it.descriptor } - internal fun

registerProperty(name: String, property: P) { + private fun

registerProperty(name: String, property: P) { if (_properties.contains(name)) error("Property with name $name already registered") _properties[name] = property } diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceProperty.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceProperty.kt index f74d5b5..4ccdc78 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceProperty.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/DeviceProperty.kt @@ -1,8 +1,8 @@ -package space.kscience.dataforge.control.base +package ru.mipt.npm.controls.base import kotlinx.coroutines.* import kotlinx.coroutines.flow.Flow -import space.kscience.dataforge.control.api.PropertyDescriptor +import ru.mipt.npm.controls.api.PropertyDescriptor import space.kscience.dataforge.meta.MetaItem import kotlin.time.Duration diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/TypedDeviceProperty.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/TypedDeviceProperty.kt index e370577..c23af1f 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/TypedDeviceProperty.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/TypedDeviceProperty.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.base +package ru.mipt.npm.controls.base import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/actionDelegates.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/actionDelegates.kt index cfa5c1c..586b5d2 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/actionDelegates.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/actionDelegates.kt @@ -1,6 +1,6 @@ -package space.kscience.dataforge.control.base +package ru.mipt.npm.controls.base -import space.kscience.dataforge.control.api.ActionDescriptor +import ru.mipt.npm.controls.api.ActionDescriptor import space.kscience.dataforge.meta.MetaBuilder import space.kscience.dataforge.meta.MetaItem import space.kscience.dataforge.meta.MetaItemNode diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/devicePropertyDelegates.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/devicePropertyDelegates.kt index 6b52179..6a89d79 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/devicePropertyDelegates.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/devicePropertyDelegates.kt @@ -1,6 +1,6 @@ -package space.kscience.dataforge.control.base +package ru.mipt.npm.controls.base -import space.kscience.dataforge.control.api.PropertyDescriptor +import ru.mipt.npm.controls.api.PropertyDescriptor import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.transformations.MetaConverter import space.kscience.dataforge.values.Null diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/misc.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/misc.kt index a4af790..78604ab 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/misc.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/base/misc.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.base +package ru.mipt.npm.controls.base import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.transformations.MetaConverter diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceController.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceController.kt index 5e0cba6..a478d3c 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceController.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceController.kt @@ -1,11 +1,8 @@ -package space.kscience.dataforge.control.controllers +package ru.mipt.npm.controls.controllers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import space.kscience.dataforge.control.api.Device -import space.kscience.dataforge.control.api.DeviceHub -import space.kscience.dataforge.control.api.getOrNull -import space.kscience.dataforge.control.messages.* +import ru.mipt.npm.controls.api.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaItem import space.kscience.dataforge.misc.DFExperimental diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceManager.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceManager.kt index 02846b9..bae7d4a 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceManager.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/DeviceManager.kt @@ -1,8 +1,8 @@ -package space.kscience.dataforge.control.controllers +package ru.mipt.npm.controls.controllers +import ru.mipt.npm.controls.api.Device +import ru.mipt.npm.controls.api.DeviceHub import space.kscience.dataforge.context.* -import space.kscience.dataforge.control.api.Device -import space.kscience.dataforge.control.api.DeviceHub import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaBuilder import space.kscience.dataforge.meta.get diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/HubController.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/HubController.kt index 09347f6..771a544 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/HubController.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/HubController.kt @@ -1,11 +1,11 @@ -package space.kscience.dataforge.control.controllers +package ru.mipt.npm.controls.controllers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.consumeAsFlow -import space.kscience.dataforge.control.api.DeviceHub -import space.kscience.dataforge.control.api.getOrNull -import space.kscience.dataforge.control.messages.DeviceMessage +import ru.mipt.npm.controls.api.DeviceHub +import ru.mipt.npm.controls.api.DeviceMessage +import ru.mipt.npm.controls.api.getOrNull import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.toName @@ -14,7 +14,7 @@ import space.kscience.dataforge.names.toName @OptIn(DFExperimental::class) public class HubController( public val hub: DeviceHub, -) { +) { private val messageOutbox = Channel(Channel.CONFLATED) diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/Port.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/Port.kt index 77d1e62..4cf672d 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/Port.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/Port.kt @@ -1,11 +1,11 @@ -package space.kscience.dataforge.control.ports +package ru.mipt.npm.controls.ports import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.receiveAsFlow +import ru.mipt.npm.controls.api.Socket import space.kscience.dataforge.context.* -import space.kscience.dataforge.control.api.Socket import kotlin.coroutines.CoroutineContext public interface Port : ContextAware, Socket diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/PortProxy.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/PortProxy.kt index 94afba9..686992d 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/PortProxy.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/PortProxy.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.ports +package ru.mipt.npm.controls.ports import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/SynchronousPortHandler.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/SynchronousPortHandler.kt index d9912f9..508ce6d 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/SynchronousPortHandler.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/SynchronousPortHandler.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.ports +package ru.mipt.npm.controls.ports import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/phrases.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/phrases.kt index d4726a9..62d075a 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/phrases.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/ports/phrases.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.ports +package ru.mipt.npm.controls.ports import io.ktor.utils.io.core.BytePacketBuilder import io.ktor.utils.io.core.readBytes diff --git a/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/controllers/delegates.kt b/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/controllers/delegates.kt index 5358f78..783d658 100644 --- a/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/controllers/delegates.kt +++ b/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/controllers/delegates.kt @@ -1,7 +1,7 @@ -package space.kscience.dataforge.control.controllers +package ru.mipt.npm.controls.controllers import kotlinx.coroutines.runBlocking -import space.kscience.dataforge.control.base.* +import ru.mipt.npm.controls.base.* import space.kscience.dataforge.meta.MetaItem import space.kscience.dataforge.meta.transformations.MetaConverter import kotlin.properties.ReadOnlyProperty diff --git a/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/TcpPort.kt b/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/TcpPort.kt index 42efab0..cfd810b 100644 --- a/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/TcpPort.kt +++ b/controls-core/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/TcpPort.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.ports +package ru.mipt.npm.controls.ports import kotlinx.coroutines.* import space.kscience.dataforge.context.Context @@ -41,7 +41,7 @@ public class TcpPort private constructor( */ public val startJob: Job get() = futureChannel - private val listenerJob = this.scope.launch { + private val listenerJob = this.scope.launch(Dispatchers.IO) { val channel = futureChannel.await() val buffer = ByteBuffer.allocate(1024) while (isActive) { diff --git a/controls-core/src/jvmTest/kotlin/ru/mipt/npm/controls/ports/PortIOTest.kt b/controls-core/src/jvmTest/kotlin/ru/mipt/npm/controls/ports/PortIOTest.kt index ba4d10f..cdb3107 100644 --- a/controls-core/src/jvmTest/kotlin/ru/mipt/npm/controls/ports/PortIOTest.kt +++ b/controls-core/src/jvmTest/kotlin/ru/mipt/npm/controls/ports/PortIOTest.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.ports +package ru.mipt.npm.controls.ports import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map diff --git a/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/dfMagix.kt b/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/dfMagix.kt index e64da5e..fa951b2 100644 --- a/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/dfMagix.kt +++ b/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/dfMagix.kt @@ -1,17 +1,17 @@ -package space.kscience.dataforge.control.client +package ru.mipt.npm.controls.client import kotlinx.coroutines.Job import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import ru.mipt.npm.controls.api.DeviceMessage +import ru.mipt.npm.controls.controllers.DeviceManager +import ru.mipt.npm.controls.controllers.respondMessage import ru.mipt.npm.magix.api.MagixEndpoint import ru.mipt.npm.magix.api.MagixMessage import space.kscience.dataforge.context.error import space.kscience.dataforge.context.logger -import space.kscience.dataforge.control.controllers.DeviceManager -import space.kscience.dataforge.control.controllers.respondMessage -import space.kscience.dataforge.control.messages.DeviceMessage public const val DATAFORGE_MAGIX_FORMAT: String = "dataforge" diff --git a/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/tangoMagix.kt b/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/tangoMagix.kt index 6cac86d..c076307 100644 --- a/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/tangoMagix.kt +++ b/controls-magix-client/src/commonMain/kotlin/ru/mipt/npm/controls/client/tangoMagix.kt @@ -5,13 +5,12 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.serialization.Serializable +import ru.mipt.npm.controls.api.get +import ru.mipt.npm.controls.controllers.DeviceManager import ru.mipt.npm.magix.api.MagixEndpoint import ru.mipt.npm.magix.api.MagixMessage import space.kscience.dataforge.context.error import space.kscience.dataforge.context.logger -import space.kscience.dataforge.control.api.get -import space.kscience.dataforge.control.client.generateId -import space.kscience.dataforge.control.controllers.DeviceManager import space.kscience.dataforge.meta.MetaItem public const val TANGO_MAGIX_FORMAT: String = "tango" @@ -64,9 +63,8 @@ public data class TangoPayload( public fun DeviceManager.launchTangoMagix( endpoint: MagixEndpoint, endpointID: String = TANGO_MAGIX_FORMAT, -): Job = context.launch { - - suspend inline fun respond(request: MagixMessage, payloadBuilder: (TangoPayload) -> TangoPayload) { +): Job { + suspend fun respond(request: MagixMessage, payloadBuilder: (TangoPayload) -> TangoPayload) { endpoint.broadcast( request.copy( id = generateId(request), @@ -77,55 +75,57 @@ public fun DeviceManager.launchTangoMagix( ) } - endpoint.subscribe().onEach { request -> - try { - val device = get(request.payload.device) - when (request.payload.action) { - TangoAction.read -> { - val value = device.getProperty(request.payload.name) - respond(request) { requestPayload -> - requestPayload.copy( - value = value, - quality = TangoQuality.VALID - ) + + return context.launch { + endpoint.subscribe().onEach { request -> + try { + val device = get(request.payload.device) + when (request.payload.action) { + TangoAction.read -> { + val value = device.getProperty(request.payload.name) + respond(request) { requestPayload -> + requestPayload.copy( + value = value, + quality = TangoQuality.VALID + ) + } } + TangoAction.write -> { + request.payload.value?.let { value -> + device.setProperty(request.payload.name, value) + } + //wait for value to be written and return final state + val value = device.getProperty(request.payload.name) + respond(request) { requestPayload -> + requestPayload.copy( + value = value, + quality = TangoQuality.VALID + ) + } + } + TangoAction.exec -> { + val result = device.execute(request.payload.name, request.payload.argin) + respond(request) { requestPayload -> + requestPayload.copy( + argout = result, + quality = TangoQuality.VALID + ) + } + } + TangoAction.pipe -> TODO("Pipe not implemented") } - TangoAction.write -> { - request.payload.value?.let { value -> - device.setProperty(request.payload.name, value) - } - //wait for value to be written and return final state - val value = device.getProperty(request.payload.name) - respond(request) { requestPayload -> - requestPayload.copy( - value = value, - quality = TangoQuality.VALID - ) - } - } - TangoAction.exec -> { - val result = device.execute(request.payload.name, request.payload.argin) - respond(request) { requestPayload -> - requestPayload.copy( - argout = result, - quality = TangoQuality.VALID - ) - } - } - TangoAction.pipe -> TODO("Pipe not implemented") - } - } catch (ex: Exception) { - logger.error(ex) { "Error while responding to message" } - endpoint.broadcast( - request.copy( - id = generateId(request), - parentId = request.id, - origin = endpointID, - payload = request.payload.copy(quality = TangoQuality.WARNING) + } catch (ex: Exception) { + logger.error(ex) { "Error while responding to message" } + endpoint.broadcast( + request.copy( + id = generateId(request), + parentId = request.id, + origin = endpointID, + payload = request.payload.copy(quality = TangoQuality.WARNING) + ) ) - ) - } - }.launchIn(this) + } + }.launchIn(this) //TODO implement subscriptions? // controller.messageOutput().onEach { payload -> @@ -140,4 +140,5 @@ public fun DeviceManager.launchTangoMagix( // }.catch { error -> // logger.error(error) { "Error while sending a message" } // }.launchIn(this) + } } \ No newline at end of file diff --git a/controls-serial/src/main/kotlin/ru/mipt/npm/controls/serial/SerialPort.kt b/controls-serial/src/main/kotlin/ru/mipt/npm/controls/serial/SerialPort.kt index 0207bde..1c9ad27 100644 --- a/controls-serial/src/main/kotlin/ru/mipt/npm/controls/serial/SerialPort.kt +++ b/controls-serial/src/main/kotlin/ru/mipt/npm/controls/serial/SerialPort.kt @@ -1,11 +1,11 @@ -package space.kscience.dataforge.control.serial +package ru.mipt.npm.controls.serial import jssc.SerialPort.* import jssc.SerialPortEventListener +import ru.mipt.npm.controls.ports.AbstractPort +import ru.mipt.npm.controls.ports.Port +import ru.mipt.npm.controls.ports.PortFactory import space.kscience.dataforge.context.Context -import space.kscience.dataforge.control.ports.AbstractPort -import space.kscience.dataforge.control.ports.Port -import space.kscience.dataforge.control.ports.PortFactory import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.string diff --git a/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/conversions.kt b/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/conversions.kt index 6f98cec..522d81a 100644 --- a/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/conversions.kt +++ b/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/conversions.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.server +package ru.mipt.npm.controls.server import io.ktor.application.ApplicationCall import io.ktor.http.ContentType @@ -7,8 +7,8 @@ import io.ktor.response.respondText import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObjectBuilder import kotlinx.serialization.json.buildJsonObject -import space.kscience.dataforge.control.messages.DeviceMessage -import space.kscience.dataforge.control.messages.toMeta +import ru.mipt.npm.controls.api.DeviceMessage +import ru.mipt.npm.controls.api.toMeta import space.kscience.dataforge.io.* import space.kscience.dataforge.meta.MetaSerializer diff --git a/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/deviceWebServer.kt b/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/deviceWebServer.kt index 386b394..41a2a85 100644 --- a/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/deviceWebServer.kt +++ b/controls-server/src/main/kotlin/ru/mipt/npm/controls/server/deviceWebServer.kt @@ -1,6 +1,6 @@ @file:OptIn(ExperimentalCoroutinesApi::class, KtorExperimentalAPI::class, FlowPreview::class) -package space.kscience.dataforge.control.server +package ru.mipt.npm.controls.server import io.ktor.application.* @@ -29,12 +29,12 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.buildJsonArray import kotlinx.serialization.json.put -import space.kscience.dataforge.control.api.getOrNull -import space.kscience.dataforge.control.controllers.DeviceManager -import space.kscience.dataforge.control.controllers.respondMessage -import space.kscience.dataforge.control.messages.DeviceMessage -import space.kscience.dataforge.control.messages.PropertyGetMessage -import space.kscience.dataforge.control.messages.PropertySetMessage +import ru.mipt.npm.controls.api.DeviceMessage +import ru.mipt.npm.controls.api.PropertyGetMessage +import ru.mipt.npm.controls.api.PropertySetMessage +import ru.mipt.npm.controls.api.getOrNull +import ru.mipt.npm.controls.controllers.DeviceManager +import ru.mipt.npm.controls.controllers.respondMessage import space.kscience.dataforge.meta.toJson import space.kscience.dataforge.meta.toMeta import space.kscience.dataforge.meta.toMetaItem @@ -42,7 +42,6 @@ import space.kscience.dataforge.meta.toMetaItem /** * Create and start a web server for several devices */ -@OptIn(KtorExperimentalAPI::class) public fun CoroutineScope.startDeviceServer( manager: DeviceManager, port: Int = 8111, diff --git a/controls-tcp/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/KtorTcpPort.kt b/controls-tcp/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/KtorTcpPort.kt index 8413334..5b47265 100644 --- a/controls-tcp/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/KtorTcpPort.kt +++ b/controls-tcp/src/jvmMain/kotlin/ru/mipt/npm/controls/ports/KtorTcpPort.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.control.ports +package ru.mipt.npm.controls.ports import io.ktor.network.selector.ActorSelectorManager import io.ktor.network.sockets.aSocket diff --git a/demo/src/main/kotlin/ru/mipt/npm/controls/demo/DemoDevice.kt b/demo/src/main/kotlin/ru/mipt/npm/controls/demo/DemoDevice.kt index ab485de..4e6622f 100644 --- a/demo/src/main/kotlin/ru/mipt/npm/controls/demo/DemoDevice.kt +++ b/demo/src/main/kotlin/ru/mipt/npm/controls/demo/DemoDevice.kt @@ -3,18 +3,18 @@ package ru.mipt.npm.controls.demo import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.asCoroutineDispatcher +import ru.mipt.npm.controls.base.* +import ru.mipt.npm.controls.controllers.double import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Factory -import space.kscience.dataforge.control.base.* -import space.kscience.dataforge.control.controllers.double import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.values.asValue import java.time.Instant import java.util.concurrent.Executors import kotlin.math.cos import kotlin.math.sin +import kotlin.time.Duration import kotlin.time.ExperimentalTime -import kotlin.time.seconds @OptIn(ExperimentalTime::class) class DemoDevice(context: Context) : DeviceBase(context) { @@ -57,9 +57,9 @@ class DemoDevice(context: Context) : DeviceBase(context) { } init { - sin.readEvery(0.2.seconds) - cos.readEvery(0.2.seconds) - coordinates.readEvery(0.3.seconds) + sin.readEvery(Duration.seconds(0.2)) + cos.readEvery(Duration.seconds(0.2)) + coordinates.readEvery(Duration.seconds(0.3)) } override fun close() { diff --git a/demo/src/main/kotlin/ru/mipt/npm/controls/demo/demoDeviceServer.kt b/demo/src/main/kotlin/ru/mipt/npm/controls/demo/demoDeviceServer.kt index 69866d6..908e2a1 100644 --- a/demo/src/main/kotlin/ru/mipt/npm/controls/demo/demoDeviceServer.kt +++ b/demo/src/main/kotlin/ru/mipt/npm/controls/demo/demoDeviceServer.kt @@ -5,10 +5,10 @@ import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.html.div import kotlinx.html.link +import ru.mipt.npm.controls.controllers.devices +import ru.mipt.npm.controls.server.startDeviceServer +import ru.mipt.npm.controls.server.whenStarted import space.kscience.dataforge.context.Context -import space.kscience.dataforge.control.controllers.devices -import space.kscience.dataforge.control.server.startDeviceServer -import space.kscience.dataforge.control.server.whenStarted import space.kscience.dataforge.meta.double import space.kscience.dataforge.names.NameToken import space.kscience.plotly.layout diff --git a/demo/src/main/kotlin/ru/mipt/npm/controls/demo/generateMessageSchema.kt b/demo/src/main/kotlin/ru/mipt/npm/controls/demo/generateMessageSchema.kt index 65faef3..420bca3 100644 --- a/demo/src/main/kotlin/ru/mipt/npm/controls/demo/generateMessageSchema.kt +++ b/demo/src/main/kotlin/ru/mipt/npm/controls/demo/generateMessageSchema.kt @@ -2,7 +2,7 @@ package ru.mipt.npm.controls.demo import com.github.ricky12awesome.jss.encodeToSchema import com.github.ricky12awesome.jss.globalJson -import space.kscience.dataforge.control.messages.DeviceMessage +import ru.mipt.npm.controls.api.DeviceMessage fun main() { val schema = globalJson.encodeToSchema(DeviceMessage.serializer(), generateDefinitions = false) diff --git a/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/MagixMessage.kt b/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/MagixMessage.kt index 3066e2d..eaf2098 100644 --- a/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/MagixMessage.kt +++ b/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/MagixMessage.kt @@ -3,11 +3,8 @@ package ru.mipt.npm.magix.api import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement -/** - * - * Magix message according to [magix specification](https://github.com/piazza-controls/rfc/tree/master/1) - * with a [correction](https://github.com/piazza-controls/rfc/issues/12) - * + +/* * { * "format": "string[required]", * "id":"string|number[optional, but desired]", @@ -19,6 +16,13 @@ import kotlinx.serialization.json.JsonElement * "payload":"object[optional]" * } */ + +/** + * + * Magix message according to [magix specification](https://github.com/piazza-controls/rfc/tree/master/1) + * with a [correction](https://github.com/piazza-controls/rfc/issues/12) + * + */ @Serializable public data class MagixMessage( val format: String, diff --git a/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/converters.kt b/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/converters.kt index deb0ee4..f1c854c 100644 --- a/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/converters.kt +++ b/magix/magix-api/src/commonMain/kotlin/ru/mipt/npm/magix/api/converters.kt @@ -1,12 +1,9 @@ -package space.kscience.dataforge.magix.api +package ru.mipt.npm.magix.api import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import ru.mipt.npm.magix.api.MagixEndpoint -import ru.mipt.npm.magix.api.MagixMessage -import ru.mipt.npm.magix.api.MagixMessageFilter /** * Launch magix message converter service diff --git a/magix/magix-java-client/src/main/kotlin/ru/mipt/npm/magix/client/ControlsMagixClient.kt b/magix/magix-java-client/src/main/kotlin/ru/mipt/npm/magix/client/ControlsMagixClient.kt index 4f7cf57..efa4c41 100644 --- a/magix/magix-java-client/src/main/kotlin/ru/mipt/npm/magix/client/ControlsMagixClient.kt +++ b/magix/magix-java-client/src/main/kotlin/ru/mipt/npm/magix/client/ControlsMagixClient.kt @@ -6,8 +6,8 @@ import kotlinx.serialization.KSerializer import ru.mipt.npm.magix.api.MagixEndpoint import ru.mipt.npm.magix.api.MagixMessage import ru.mipt.npm.magix.api.MagixMessageFilter -import space.kscience.dataforge.magix.service.RSocketMagixEndpoint -import space.kscience.dataforge.magix.service.withTcp +import ru.mipt.npm.magix.service.RSocketMagixEndpoint +import ru.mipt.npm.magix.service.withTcp import java.util.concurrent.Flow public class ControlsMagixClient( diff --git a/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/MagixServer.kt b/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/MagixServer.kt index 483e994..cbd15f5 100644 --- a/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/MagixServer.kt +++ b/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/MagixServer.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.magix.server +package ru.mipt.npm.magix.server import io.ktor.network.selector.ActorSelectorManager import io.ktor.network.sockets.aSocket @@ -13,9 +13,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import ru.mipt.npm.magix.api.MagixEndpoint.Companion.DEFAULT_MAGIX_RAW_PORT import ru.mipt.npm.magix.api.MagixEndpoint.Companion.DEFAULT_MAGIX_WS_PORT -import ru.mipt.npm.magix.server.GenericMagixMessage -import ru.mipt.npm.magix.server.magixAcceptor -import ru.mipt.npm.magix.server.magixModule @OptIn(KtorExperimentalAPI::class) public fun CoroutineScope.startMagixServer( diff --git a/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/magixModule.kt b/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/magixModule.kt index 8fc0ced..e2a1980 100644 --- a/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/magixModule.kt +++ b/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/magixModule.kt @@ -29,8 +29,6 @@ import ru.mipt.npm.magix.api.MagixEndpoint.Companion.magixJson import ru.mipt.npm.magix.api.MagixMessage import ru.mipt.npm.magix.api.MagixMessageFilter import ru.mipt.npm.magix.api.filter -import space.kscience.dataforge.magix.server.SseEvent -import space.kscience.dataforge.magix.server.respondSse import java.util.* public typealias GenericMagixMessage = MagixMessage diff --git a/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/sse.kt b/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/sse.kt index a574a85..72bfeb1 100644 --- a/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/sse.kt +++ b/magix/magix-server/src/main/kotlin/ru/mipt/npm/magix/server/sse.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.magix.server +package ru.mipt.npm.magix.server import io.ktor.application.ApplicationCall import io.ktor.http.CacheControl diff --git a/magix/magix-service/src/commonMain/kotlin/ru/mipt/npm/magix/service/RSocketMagixEndpoint.kt b/magix/magix-service/src/commonMain/kotlin/ru/mipt/npm/magix/service/RSocketMagixEndpoint.kt index b6d6d15..111ba9b 100644 --- a/magix/magix-service/src/commonMain/kotlin/ru/mipt/npm/magix/service/RSocketMagixEndpoint.kt +++ b/magix/magix-service/src/commonMain/kotlin/ru/mipt/npm/magix/service/RSocketMagixEndpoint.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.magix.service +package ru.mipt.npm.magix.service import io.ktor.client.HttpClient import io.ktor.client.features.websocket.WebSockets diff --git a/magix/magix-service/src/jvmMain/kotlin/ru/mipt/npm/magix/service/withTcp.kt b/magix/magix-service/src/jvmMain/kotlin/ru/mipt/npm/magix/service/withTcp.kt index 63f37e4..133b379 100644 --- a/magix/magix-service/src/jvmMain/kotlin/ru/mipt/npm/magix/service/withTcp.kt +++ b/magix/magix-service/src/jvmMain/kotlin/ru/mipt/npm/magix/service/withTcp.kt @@ -1,4 +1,4 @@ -package space.kscience.dataforge.magix.service +package ru.mipt.npm.magix.service import io.ktor.network.selector.ActorSelectorManager import io.ktor.network.sockets.SocketOptions diff --git a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt index 8cce497..67d475f 100644 --- a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt +++ b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt @@ -11,10 +11,10 @@ import javafx.scene.layout.VBox import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch +import ru.mipt.npm.controls.controllers.DeviceManager +import ru.mipt.npm.controls.controllers.installing import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.fetch -import space.kscience.dataforge.control.controllers.DeviceManager -import space.kscience.dataforge.control.controllers.installing import tornadofx.* class PiMotionMasterApp : App(PiMotionMasterView::class) diff --git a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice.kt b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice.kt index 409627c..4ba95fa 100644 --- a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice.kt +++ b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice.kt @@ -3,21 +3,22 @@ package ru.mipt.npm.devices.pimotionmaster import kotlinx.coroutines.* -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.transformWhile import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import ru.mipt.npm.controls.api.DeviceHub +import ru.mipt.npm.controls.api.PropertyDescriptor +import ru.mipt.npm.controls.base.* +import ru.mipt.npm.controls.controllers.DeviceFactory +import ru.mipt.npm.controls.controllers.duration +import ru.mipt.npm.controls.ports.* import space.kscience.dataforge.context.* -import space.kscience.dataforge.control.api.DeviceHub -import space.kscience.dataforge.control.api.PropertyDescriptor -import space.kscience.dataforge.control.base.* -import space.kscience.dataforge.control.controllers.* -import space.kscience.dataforge.control.ports.* import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.values.asValue -import tornadofx.* -import java.util.* -import kotlin.error +import kotlin.collections.component1 +import kotlin.collections.component2 import kotlin.time.Duration class PiMotionMasterDevice( diff --git a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterVirtualDevice.kt b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterVirtualDevice.kt index efd49c8..cb490e1 100644 --- a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterVirtualDevice.kt +++ b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterVirtualDevice.kt @@ -5,10 +5,10 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import ru.mipt.npm.controls.api.Socket +import ru.mipt.npm.controls.ports.AbstractPort +import ru.mipt.npm.controls.ports.withDelimiter import space.kscience.dataforge.context.* -import space.kscience.dataforge.control.api.Socket -import space.kscience.dataforge.control.ports.AbstractPort -import space.kscience.dataforge.control.ports.withDelimiter import kotlin.math.abs import kotlin.time.Duration @@ -167,7 +167,7 @@ class PiMotionMasterVirtualDevice( } override suspend fun evaluateRequest(request: ByteArray) { - assert(request.last() == '\n'.toByte()) + assert(request.last() == '\n'.code.toByte()) val string = request.decodeToString().substringBefore("\n") .dropWhile { it != '*' && it != '#' && it !in 'A'..'Z' } //filter junk symbols at the beginning of the line diff --git a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/fxDeviceProperties.kt b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/fxDeviceProperties.kt index c865058..48ef6d2 100644 --- a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/fxDeviceProperties.kt +++ b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/fxDeviceProperties.kt @@ -6,11 +6,11 @@ import javafx.beans.property.ReadOnlyProperty import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import ru.mipt.npm.controls.api.Device +import ru.mipt.npm.controls.base.TypedDeviceProperty +import ru.mipt.npm.controls.base.TypedReadOnlyDeviceProperty import space.kscience.dataforge.context.info import space.kscience.dataforge.context.logger -import space.kscience.dataforge.control.api.Device -import space.kscience.dataforge.control.base.TypedDeviceProperty -import space.kscience.dataforge.control.base.TypedReadOnlyDeviceProperty import tornadofx.* fun TypedReadOnlyDeviceProperty.fxProperty(ownerDevice: Device?): ReadOnlyProperty = diff --git a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/piDebugServer.kt b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/piDebugServer.kt index e1e5e61..f5a4c81 100644 --- a/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/piDebugServer.kt +++ b/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/piDebugServer.kt @@ -5,7 +5,6 @@ import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openWriteChannel import io.ktor.util.InternalAPI -import io.ktor.util.KtorExperimentalAPI import io.ktor.util.moveToByteArray import io.ktor.utils.io.writeAvailable import kotlinx.coroutines.* @@ -18,7 +17,7 @@ val exceptionHandler = CoroutineExceptionHandler { _, throwable -> throwable.printStackTrace() } -@OptIn(KtorExperimentalAPI::class, InternalAPI::class) +@OptIn(InternalAPI::class) fun Context.launchPiDebugServer(port: Int, axes: List): Job = launch(exceptionHandler) { val virtualDevice = PiMotionMasterVirtualDevice(this@launchPiDebugServer, axes) val server = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().bind(InetSocketAddress("localhost", port))