Merge pull request #9 from SciProgCentre/dev
0.2.0
This commit is contained in:
commit
5b655a9354
32
CHANGELOG.md
Normal file
32
CHANGELOG.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Core interfaces for building a device server
|
||||||
|
- Magix service for binding controls devices (both as RPC client and server)
|
||||||
|
- A plugin for Controls-kt device server on top of modbus-rtu/modbus-tcp protocols
|
||||||
|
- A client and server connectors for OPC-UA via Eclipse Milo
|
||||||
|
- Implementation of byte ports on top os ktor-io asynchronous API
|
||||||
|
- Implementation of direct serial port communication with JSerialComm
|
||||||
|
- A combined Magix event loop server with web server for visualization.
|
||||||
|
- An API for stand-alone Controls-kt device or a hub.
|
||||||
|
- An implementation of controls-storage on top of JetBrains Xodus.
|
||||||
|
- A kotlin API for magix standard and some zero-dependency magix services
|
||||||
|
- Java API to work with magix endpoints without Kotlin
|
||||||
|
- MQTT client magix endpoint
|
||||||
|
- RabbitMQ client magix endpoint
|
||||||
|
- Magix endpoint (client) based on RSocket
|
||||||
|
- A magix event loop implementation in Kotlin. Includes HTTP/SSE and RSocket routes.
|
||||||
|
- Magix history database API
|
||||||
|
- ZMQ client endpoint for Magix
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
### Security
|
81
README.md
81
README.md
@ -43,7 +43,7 @@ Example view of a demo:
|
|||||||
|
|
||||||
|
|
||||||
### [controls-core](controls-core)
|
### [controls-core](controls-core)
|
||||||
>
|
> Core interfaces for building a device server
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
>
|
>
|
||||||
@ -51,136 +51,151 @@ Example view of a demo:
|
|||||||
> - [device](controls-core/src/commonMain/kotlin/space/kscience/controls/api/Device.kt) : Device API with subscription (asynchronous and pseudo-synchronous properties)
|
> - [device](controls-core/src/commonMain/kotlin/space/kscience/controls/api/Device.kt) : Device API with subscription (asynchronous and pseudo-synchronous properties)
|
||||||
> - [deviceMessage](controls-core/src/commonMain/kotlin/space/kscience/controls/api/DeviceMessage.kt) : Specification for messages used to communicate between Controls-kt devices.
|
> - [deviceMessage](controls-core/src/commonMain/kotlin/space/kscience/controls/api/DeviceMessage.kt) : Specification for messages used to communicate between Controls-kt devices.
|
||||||
> - [deviceHub](controls-core/src/commonMain/kotlin/space/kscience/controls/api/DeviceHub.kt) : Grouping of devices into local tree-like hubs.
|
> - [deviceHub](controls-core/src/commonMain/kotlin/space/kscience/controls/api/DeviceHub.kt) : Grouping of devices into local tree-like hubs.
|
||||||
|
> - [deviceSpec](controls-core/src/commonMain/kotlin/space/kscience/controls/spec) : Mechanics and type-safe builders for devices. Including separation of device specification and device state.
|
||||||
|
> - [deviceManager](controls-core/src/commonMain/kotlin/space/kscience/controls/manager) : DataForge DI integration for devices. Includes device builders.
|
||||||
|
> - [ports](controls-core/src/commonMain/kotlin/space/kscience/controls/ports) : Working with asynchronous data sending and receiving raw byte arrays
|
||||||
|
|
||||||
|
|
||||||
### [controls-ktor-tcp](controls-ktor-tcp)
|
### [controls-magix](controls-magix)
|
||||||
>
|
> Magix service for binding controls devices (both as RPC client and server)
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
>
|
||||||
|
> **Features:**
|
||||||
|
> - [controlsMagix](controls-magix/src/commonMain/kotlin/space/kscience/controls/client/controlsMagix.kt) : Connect a `DeviceManage` with one or many devices to the Magix endpoint
|
||||||
|
> - [DeviceClient](controls-magix/src/commonMain/kotlin/space/kscience/controls/client/DeviceClient.kt) : A remote connector to Controls-kt device via Magix
|
||||||
|
|
||||||
### [controls-magix-client](controls-magix-client)
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
|
||||||
|
|
||||||
### [controls-modbus](controls-modbus)
|
### [controls-modbus](controls-modbus)
|
||||||
>
|
> A plugin for Controls-kt device server on top of modbus-rtu/modbus-tcp protocols
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
>
|
||||||
|
> **Features:**
|
||||||
|
> - [modbusRegistryMap](controls-modbus/src/main/kotlin/space/kscience/controls/modbus/ModbusRegistryMap.kt) : Type-safe modbus registry map. Allows to define both single-register and multi-register entries (using DataForge IO).
|
||||||
|
Automatically checks consistency.
|
||||||
|
> - [modbusProcessImage](controls-modbus/src/main/kotlin/space/kscience/controls/modbus/DeviceProcessImage.kt) : Binding of slave (server) modbus device to Controls-kt device
|
||||||
|
> - [modbusDevice](controls-modbus/src/main/kotlin/space/kscience/controls/modbus/ModbusDevice.kt) : A device with additional methods to work with modbus registers.
|
||||||
|
|
||||||
|
|
||||||
### [controls-opcua](controls-opcua)
|
### [controls-opcua](controls-opcua)
|
||||||
|
> A client and server connectors for OPC-UA via Eclipse Milo
|
||||||
>
|
>
|
||||||
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
>
|
||||||
|
> **Features:**
|
||||||
|
> - [opcuaClient](controls-opcua/src/main/kotlin/space/kscience/controls/opcua/client) : Connect a Controls-kt as a client to OPC UA server
|
||||||
|
> - [opcuaServer](controls-opcua/src/main/kotlin/space/kscience/controls/opcua/server) : Create an OPC UA server on top of Controls-kt device (or device hub)
|
||||||
|
|
||||||
|
|
||||||
|
### [controls-pi](controls-pi)
|
||||||
|
> Utils to work with controls-kt on Raspberry pi
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [controls-serial](controls-serial)
|
### [controls-ports-ktor](controls-ports-ktor)
|
||||||
|
> Implementation of byte ports on top os ktor-io asynchronous API
|
||||||
>
|
>
|
||||||
|
> **Maturity**: PROTOTYPE
|
||||||
|
|
||||||
|
### [controls-serial](controls-serial)
|
||||||
|
> Implementation of direct serial port communication with JSerialComm
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [controls-server](controls-server)
|
### [controls-server](controls-server)
|
||||||
|
> A combined Magix event loop server with web server for visualization.
|
||||||
>
|
>
|
||||||
>
|
> **Maturity**: PROTOTYPE
|
||||||
> **Maturity**: EXPERIMENTAL
|
|
||||||
|
|
||||||
### [controls-storage](controls-storage)
|
### [controls-storage](controls-storage)
|
||||||
>
|
> An API for stand-alone Controls-kt device or a hub.
|
||||||
>
|
>
|
||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
|
|
||||||
### [demo](demo)
|
### [demo](demo)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [magix](magix)
|
### [magix](magix)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [controls-storage/controls-xodus](controls-storage/controls-xodus)
|
### [controls-storage/controls-xodus](controls-storage/controls-xodus)
|
||||||
>
|
> An implementation of controls-storage on top of JetBrains Xodus.
|
||||||
>
|
>
|
||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
|
|
||||||
### [demo/all-things](demo/all-things)
|
### [demo/all-things](demo/all-things)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [demo/car](demo/car)
|
### [demo/car](demo/car)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [demo/echo](demo/echo)
|
### [demo/echo](demo/echo)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [demo/magix-demo](demo/magix-demo)
|
### [demo/magix-demo](demo/magix-demo)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [demo/many-devices](demo/many-devices)
|
### [demo/many-devices](demo/many-devices)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [demo/mks-pdr900](demo/mks-pdr900)
|
### [demo/mks-pdr900](demo/mks-pdr900)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [demo/motors](demo/motors)
|
### [demo/motors](demo/motors)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [magix/magix-api](magix/magix-api)
|
### [magix/magix-api](magix/magix-api)
|
||||||
>
|
> A kotlin API for magix standard and some zero-dependency magix services
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [magix/magix-java-client](magix/magix-java-client)
|
### [magix/magix-java-endpoint](magix/magix-java-endpoint)
|
||||||
>
|
> Java API to work with magix endpoints without Kotlin
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [magix/magix-mqtt](magix/magix-mqtt)
|
### [magix/magix-mqtt](magix/magix-mqtt)
|
||||||
>
|
> MQTT client magix endpoint
|
||||||
>
|
>
|
||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
|
|
||||||
### [magix/magix-rabbit](magix/magix-rabbit)
|
### [magix/magix-rabbit](magix/magix-rabbit)
|
||||||
>
|
> RabbitMQ client magix endpoint
|
||||||
>
|
>
|
||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
|
|
||||||
### [magix/magix-rsocket](magix/magix-rsocket)
|
### [magix/magix-rsocket](magix/magix-rsocket)
|
||||||
>
|
> Magix endpoint (client) based on RSocket
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [magix/magix-server](magix/magix-server)
|
### [magix/magix-server](magix/magix-server)
|
||||||
>
|
> A magix event loop implementation in Kotlin. Includes HTTP/SSE and RSocket routes.
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [magix/magix-storage](magix/magix-storage)
|
### [magix/magix-storage](magix/magix-storage)
|
||||||
|
> Magix history database API
|
||||||
>
|
>
|
||||||
>
|
> **Maturity**: PROTOTYPE
|
||||||
> **Maturity**: EXPERIMENTAL
|
|
||||||
|
|
||||||
### [magix/magix-zmq](magix/magix-zmq)
|
### [magix/magix-zmq](magix/magix-zmq)
|
||||||
>
|
> ZMQ client endpoint for Magix
|
||||||
>
|
>
|
||||||
> **Maturity**: EXPERIMENTAL
|
> **Maturity**: EXPERIMENTAL
|
||||||
|
|
||||||
### [magix/magix-storage/magix-storage-xodus](magix/magix-storage/magix-storage-xodus)
|
### [magix/magix-storage/magix-storage-xodus](magix/magix-storage/magix-storage-xodus)
|
||||||
>
|
>
|
||||||
>
|
|
||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,14 +6,14 @@ plugins {
|
|||||||
id("space.kscience.gradle.project")
|
id("space.kscience.gradle.project")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by extra("0.6.1")
|
val dataforgeVersion: String by extra("0.6.2-dev-3")
|
||||||
val ktorVersion: String by extra(space.kscience.gradle.KScienceVersions.ktorVersion)
|
val ktorVersion: String by extra(space.kscience.gradle.KScienceVersions.ktorVersion)
|
||||||
val rsocketVersion by extra("0.15.4")
|
val rsocketVersion by extra("0.15.4")
|
||||||
val xodusVersion by extra("2.0.1")
|
val xodusVersion by extra("2.0.1")
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
group = "space.kscience"
|
group = "space.kscience"
|
||||||
version = "0.2.0-dev-1"
|
version = "0.2.0"
|
||||||
repositories{
|
repositories{
|
||||||
maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
}
|
}
|
||||||
@ -29,10 +29,9 @@ ksciencePublish {
|
|||||||
if (isInDevelopment) {
|
if (isInDevelopment) {
|
||||||
"https://maven.pkg.jetbrains.space/spc/p/sci/dev"
|
"https://maven.pkg.jetbrains.space/spc/p/sci/dev"
|
||||||
} else {
|
} else {
|
||||||
"https://maven.pkg.jetbrains.space/spc/p/sci/release"
|
"https://maven.pkg.jetbrains.space/spc/p/sci/maven"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
space("https://maven.pkg.jetbrains.space/spc/p/controls/maven")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
|
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
|
33
controls-core/README.md
Normal file
33
controls-core/README.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Module controls-core
|
||||||
|
|
||||||
|
Core interfaces for building a device server
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [device](src/commonMain/kotlin/space/kscience/controls/api/Device.kt) : Device API with subscription (asynchronous and pseudo-synchronous properties)
|
||||||
|
- [deviceMessage](src/commonMain/kotlin/space/kscience/controls/api/DeviceMessage.kt) : Specification for messages used to communicate between Controls-kt devices.
|
||||||
|
- [deviceHub](src/commonMain/kotlin/space/kscience/controls/api/DeviceHub.kt) : Grouping of devices into local tree-like hubs.
|
||||||
|
- [deviceSpec](src/commonMain/kotlin/space/kscience/controls/spec) : Mechanics and type-safe builders for devices. Including separation of device specification and device state.
|
||||||
|
- [deviceManager](src/commonMain/kotlin/space/kscience/controls/manager) : DataForge DI integration for devices. Includes device builders.
|
||||||
|
- [ports](src/commonMain/kotlin/space/kscience/controls/ports) : Working with asynchronous data sending and receiving raw byte arrays
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## Artifact:
|
||||||
|
|
||||||
|
The Maven coordinates of this project are `space.kscience:controls-core:0.2.0`.
|
||||||
|
|
||||||
|
**Gradle Kotlin DSL:**
|
||||||
|
```kotlin
|
||||||
|
repositories {
|
||||||
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("space.kscience:controls-core:0.2.0")
|
||||||
|
}
|
||||||
|
```
|
915
controls-core/api/controls-core.api
Normal file
915
controls-core/api/controls-core.api
Normal file
@ -0,0 +1,915 @@
|
|||||||
|
public final class space/kscience/controls/api/ActionDescriptor {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/ActionDescriptor$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;)V
|
||||||
|
public final fun getInfo ()Ljava/lang/String;
|
||||||
|
public final fun getName ()Ljava/lang/String;
|
||||||
|
public final fun setInfo (Ljava/lang/String;)V
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/ActionDescriptor;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionDescriptor$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/ActionDescriptor$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/ActionDescriptor;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/ActionDescriptor;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionDescriptor$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionExecuteMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/ActionExecuteMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component3 ()Ljava/lang/String;
|
||||||
|
public final fun component4 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component5 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component6 ()Ljava/lang/String;
|
||||||
|
public final fun component7 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/ActionExecuteMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/ActionExecuteMessage;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/ActionExecuteMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getAction ()Ljava/lang/String;
|
||||||
|
public final fun getArgument ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getRequestId ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/ActionExecuteMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionExecuteMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/ActionExecuteMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/ActionExecuteMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/ActionExecuteMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionExecuteMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionResultMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/ActionResultMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component3 ()Ljava/lang/String;
|
||||||
|
public final fun component4 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component5 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component6 ()Ljava/lang/String;
|
||||||
|
public final fun component7 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/ActionResultMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/ActionResultMessage;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/ActionResultMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getAction ()Ljava/lang/String;
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getRequestId ()Ljava/lang/String;
|
||||||
|
public final fun getResult ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/ActionResultMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionResultMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/ActionResultMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/ActionResultMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/ActionResultMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/ActionResultMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/BinaryNotificationMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/BinaryNotificationMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component3 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component4 ()Ljava/lang/String;
|
||||||
|
public final fun component5 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/BinaryNotificationMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/BinaryNotificationMessage;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/BinaryNotificationMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getBinaryID ()Ljava/lang/String;
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/BinaryNotificationMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/BinaryNotificationMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/BinaryNotificationMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/BinaryNotificationMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/BinaryNotificationMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/BinaryNotificationMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DescriptionMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/DescriptionMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILspace/kscience/dataforge/meta/Meta;Ljava/util/Collection;Ljava/util/Collection;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/meta/Meta;Ljava/util/Collection;Ljava/util/Collection;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Meta;Ljava/util/Collection;Ljava/util/Collection;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component2 ()Ljava/util/Collection;
|
||||||
|
public final fun component3 ()Ljava/util/Collection;
|
||||||
|
public final fun component4 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component5 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component6 ()Ljava/lang/String;
|
||||||
|
public final fun component7 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Lspace/kscience/dataforge/meta/Meta;Ljava/util/Collection;Ljava/util/Collection;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/DescriptionMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/DescriptionMessage;Lspace/kscience/dataforge/meta/Meta;Ljava/util/Collection;Ljava/util/Collection;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/DescriptionMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getActions ()Ljava/util/Collection;
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getDescription ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun getProperties ()Ljava/util/Collection;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/DescriptionMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DescriptionMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/DescriptionMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/DescriptionMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/DescriptionMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DescriptionMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DescriptorsKt {
|
||||||
|
public static final fun metaDescriptor (Lspace/kscience/controls/api/PropertyDescriptor;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/api/Device : java/lang/AutoCloseable, kotlinx/coroutines/CoroutineScope, space/kscience/dataforge/context/ContextAware {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/Device$Companion;
|
||||||
|
public static final field DEVICE_TARGET Ljava/lang/String;
|
||||||
|
public fun close ()V
|
||||||
|
public abstract fun execute (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun execute$default (Lspace/kscience/controls/api/Device;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||||
|
public abstract fun getActionDescriptors ()Ljava/util/Collection;
|
||||||
|
public abstract fun getLifecycleState ()Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
public abstract fun getMessageFlow ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public fun getMeta ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public abstract fun getProperty (Ljava/lang/String;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public abstract fun getPropertyDescriptors ()Ljava/util/Collection;
|
||||||
|
public abstract fun invalidate (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun open (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun open$suspendImpl (Lspace/kscience/controls/api/Device;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public abstract fun readProperty (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public abstract fun writeProperty (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/Device$Companion {
|
||||||
|
public static final field DEVICE_TARGET Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceErrorMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/DeviceErrorMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Ljava/lang/String;
|
||||||
|
public final fun component3 ()Ljava/lang/String;
|
||||||
|
public final fun component4 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component5 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component6 ()Ljava/lang/String;
|
||||||
|
public final fun component7 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/DeviceErrorMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/DeviceErrorMessage;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/DeviceErrorMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getErrorMessage ()Ljava/lang/String;
|
||||||
|
public final fun getErrorStackTrace ()Ljava/lang/String;
|
||||||
|
public final fun getErrorType ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/DeviceErrorMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceErrorMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/DeviceErrorMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/DeviceErrorMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/DeviceErrorMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceErrorMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/api/DeviceHub : space/kscience/dataforge/provider/Provider {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/DeviceHub$Companion;
|
||||||
|
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||||
|
public fun getDefaultChainTarget ()Ljava/lang/String;
|
||||||
|
public fun getDefaultTarget ()Ljava/lang/String;
|
||||||
|
public abstract fun getDevices ()Ljava/util/Map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceHub$Companion {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceHubKt {
|
||||||
|
public static final fun execute (Lspace/kscience/controls/api/DeviceHub;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun get (Lspace/kscience/controls/api/DeviceHub;Ljava/lang/String;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static final fun get (Lspace/kscience/controls/api/DeviceHub;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static final fun get (Lspace/kscience/controls/api/DeviceHub;Lspace/kscience/dataforge/names/NameToken;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static final fun getOrNull (Lspace/kscience/controls/api/DeviceHub;Ljava/lang/String;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static final fun getOrNull (Lspace/kscience/controls/api/DeviceHub;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static final fun readProperty (Lspace/kscience/controls/api/DeviceHub;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun writeProperty (Lspace/kscience/controls/api/DeviceHub;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceKt {
|
||||||
|
public static final fun getAllProperties (Lspace/kscience/controls/api/Device;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public static final fun getOrReadProperty (Lspace/kscience/controls/api/Device;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun onPropertyChange (Lspace/kscience/controls/api/Device;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceLifecycleState : java/lang/Enum {
|
||||||
|
public static final field CLOSED Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
public static final field INIT Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
public static final field OPEN Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||||
|
public static fun valueOf (Ljava/lang/String;)Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
public static fun values ()[Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceLogMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/DeviceLogMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component3 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component4 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component5 ()Ljava/lang/String;
|
||||||
|
public final fun component6 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/DeviceLogMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/DeviceLogMessage;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/DeviceLogMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getData ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun getMessage ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/DeviceLogMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceLogMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/DeviceLogMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/DeviceLogMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/DeviceLogMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceLogMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/DeviceMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public abstract fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public abstract fun getComment ()Ljava/lang/String;
|
||||||
|
public abstract fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public abstract fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public abstract fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/DeviceMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceMessage$Companion {
|
||||||
|
public final fun error (Ljava/lang/Throwable;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/controls/api/DeviceErrorMessage;
|
||||||
|
public static synthetic fun error$default (Lspace/kscience/controls/api/DeviceMessage$Companion;Ljava/lang/Throwable;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lspace/kscience/controls/api/DeviceErrorMessage;
|
||||||
|
public final fun fromMeta (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/DeviceMessageKt {
|
||||||
|
public static final fun toEnvelope (Lspace/kscience/controls/api/DeviceMessage;)Lspace/kscience/dataforge/io/Envelope;
|
||||||
|
public static final fun toMeta (Lspace/kscience/controls/api/DeviceMessage;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/EmptyDeviceMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/EmptyDeviceMessage$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public synthetic fun <init> (ILspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component3 ()Ljava/lang/String;
|
||||||
|
public final fun component4 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/EmptyDeviceMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/EmptyDeviceMessage;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/EmptyDeviceMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/EmptyDeviceMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/EmptyDeviceMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/EmptyDeviceMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/EmptyDeviceMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/EmptyDeviceMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/EmptyDeviceMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/GetDescriptionMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/GetDescriptionMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component3 ()Ljava/lang/String;
|
||||||
|
public final fun component4 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/GetDescriptionMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/GetDescriptionMessage;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/GetDescriptionMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/GetDescriptionMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/GetDescriptionMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/GetDescriptionMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/GetDescriptionMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/GetDescriptionMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/GetDescriptionMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyChangedMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/PropertyChangedMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component3 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component4 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component5 ()Ljava/lang/String;
|
||||||
|
public final fun component6 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/PropertyChangedMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/PropertyChangedMessage;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/PropertyChangedMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getProperty ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun getValue ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/PropertyChangedMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyChangedMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/PropertyChangedMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/PropertyChangedMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/PropertyChangedMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyChangedMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyDescriptor {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/PropertyDescriptor$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;ZZLkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;ZZ)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun getInfo ()Ljava/lang/String;
|
||||||
|
public final fun getMetaDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;
|
||||||
|
public final fun getName ()Ljava/lang/String;
|
||||||
|
public final fun getReadable ()Z
|
||||||
|
public final fun getWritable ()Z
|
||||||
|
public final fun setInfo (Ljava/lang/String;)V
|
||||||
|
public final fun setMetaDescriptor (Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor;)V
|
||||||
|
public final fun setReadable (Z)V
|
||||||
|
public final fun setWritable (Z)V
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/PropertyDescriptor;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyDescriptor$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/PropertyDescriptor$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/PropertyDescriptor;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/PropertyDescriptor;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyDescriptor$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyGetMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/PropertyGetMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component3 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component4 ()Ljava/lang/String;
|
||||||
|
public final fun component5 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/PropertyGetMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/PropertyGetMessage;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/PropertyGetMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getProperty ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/PropertyGetMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyGetMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/PropertyGetMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/PropertyGetMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/PropertyGetMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertyGetMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertySetMessage : space/kscience/controls/api/DeviceMessage {
|
||||||
|
public static final field Companion Lspace/kscience/controls/api/PropertySetMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun changeSource (Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/api/DeviceMessage;
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component3 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component4 ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public final fun component5 ()Ljava/lang/String;
|
||||||
|
public final fun component6 ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun copy (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;)Lspace/kscience/controls/api/PropertySetMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/api/PropertySetMessage;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlinx/datetime/Instant;ILjava/lang/Object;)Lspace/kscience/controls/api/PropertySetMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getComment ()Ljava/lang/String;
|
||||||
|
public final fun getProperty ()Ljava/lang/String;
|
||||||
|
public fun getSourceDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTargetDevice ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public fun getTime ()Lkotlinx/datetime/Instant;
|
||||||
|
public final fun getValue ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/api/PropertySetMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertySetMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/api/PropertySetMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/api/PropertySetMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/api/PropertySetMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/PropertySetMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/api/Socket : java/io/Closeable {
|
||||||
|
public abstract fun isOpen ()Z
|
||||||
|
public abstract fun receiving ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public abstract fun send (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/api/SocketKt {
|
||||||
|
public static final fun connectInput (Lspace/kscience/controls/api/Socket;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/manager/DeviceManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/controls/api/DeviceHub {
|
||||||
|
public static final field Companion Lspace/kscience/controls/manager/DeviceManager$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||||
|
public fun getDevices ()Ljava/util/Map;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
public final fun registerDevice (Lspace/kscience/dataforge/names/NameToken;Lspace/kscience/controls/api/Device;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/manager/DeviceManager$Companion : space/kscience/dataforge/context/PluginFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/manager/DeviceManager;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/manager/DeviceManagerKt {
|
||||||
|
public static final fun install (Lspace/kscience/controls/manager/DeviceManager;Ljava/lang/String;Lspace/kscience/controls/api/Device;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static final fun install (Lspace/kscience/controls/manager/DeviceManager;Ljava/lang/String;Lspace/kscience/dataforge/context/Factory;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static synthetic fun install$default (Lspace/kscience/controls/manager/DeviceManager;Ljava/lang/String;Lspace/kscience/dataforge/context/Factory;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lspace/kscience/controls/api/Device;
|
||||||
|
public static final fun installing (Lspace/kscience/controls/manager/DeviceManager;Lspace/kscience/dataforge/context/Factory;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty;
|
||||||
|
public static synthetic fun installing$default (Lspace/kscience/controls/manager/DeviceManager;Lspace/kscience/dataforge/context/Factory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/manager/RespondMessageKt {
|
||||||
|
public static final fun hubMessageFlow (Lspace/kscience/controls/api/DeviceHub;Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public static final fun respondHubMessage (Lspace/kscience/controls/api/DeviceHub;Lspace/kscience/controls/api/DeviceMessage;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun respondMessage (Lspace/kscience/controls/api/Device;Lspace/kscience/dataforge/names/Name;Lspace/kscience/controls/api/DeviceMessage;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/misc/TimeMetaKt {
|
||||||
|
public static final fun instant (Lspace/kscience/dataforge/meta/Meta;)Lkotlinx/datetime/Instant;
|
||||||
|
public static final fun toMeta (Lkotlinx/datetime/Instant;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/controls/ports/AbstractPort : space/kscience/controls/ports/Port {
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/coroutines/CoroutineContext;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
protected final fun getScope ()Lkotlinx/coroutines/CoroutineScope;
|
||||||
|
public fun isOpen ()Z
|
||||||
|
protected final fun receive ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun receiving ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public synthetic fun send (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun send ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
protected abstract fun write ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/ChannelPort : space/kscience/controls/ports/AbstractPort, java/lang/AutoCloseable {
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public final fun getStartJob ()Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/ChannelPortKt {
|
||||||
|
public static final fun toArray (Ljava/nio/ByteBuffer;I)[B
|
||||||
|
public static synthetic fun toArray$default (Ljava/nio/ByteBuffer;IILjava/lang/Object;)[B
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/JvmPortsPlugin : space/kscience/dataforge/context/AbstractPlugin {
|
||||||
|
public static final field Companion Lspace/kscience/controls/ports/JvmPortsPlugin$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||||
|
public final fun getPorts ()Lspace/kscience/controls/ports/Ports;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/JvmPortsPlugin$Companion : space/kscience/dataforge/context/PluginFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/JvmPortsPlugin;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/PhrasesKt {
|
||||||
|
public static final fun delimitedIncoming (Lspace/kscience/controls/ports/Port;[B)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public static final fun stringsDelimitedIncoming (Lspace/kscience/controls/ports/Port;Ljava/lang/String;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public static final fun withDelimiter (Lkotlinx/coroutines/flow/Flow;[B)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public static final fun withStringDelimiter (Lkotlinx/coroutines/flow/Flow;Ljava/lang/String;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/ports/Port : space/kscience/controls/api/Socket, space/kscience/dataforge/context/ContextAware {
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/ports/PortFactory : space/kscience/dataforge/context/Factory {
|
||||||
|
public static final field Companion Lspace/kscience/controls/ports/PortFactory$Companion;
|
||||||
|
public static final field TYPE Ljava/lang/String;
|
||||||
|
public abstract fun getType ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/PortFactory$Companion {
|
||||||
|
public static final field TYPE Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/PortKt {
|
||||||
|
public static final fun send (Lspace/kscience/controls/ports/Port;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/PortProxy : space/kscience/controls/ports/Port, space/kscience/dataforge/context/ContextAware {
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public final fun getFactory ()Lkotlin/jvm/functions/Function1;
|
||||||
|
public fun isOpen ()Z
|
||||||
|
public fun receiving ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public synthetic fun send (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun send ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/Ports : space/kscience/dataforge/context/AbstractPlugin {
|
||||||
|
public static final field Companion Lspace/kscience/controls/ports/Ports$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun buildPort (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/Port;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/Ports$Companion : space/kscience/dataforge/context/PluginFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/Ports;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/SynchronousPort : space/kscience/controls/ports/Port {
|
||||||
|
public fun <init> (Lspace/kscience/controls/ports/Port;Lkotlinx/coroutines/sync/Mutex;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public final fun getPort ()Lspace/kscience/controls/ports/Port;
|
||||||
|
public fun isOpen ()Z
|
||||||
|
public fun receiving ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public final fun respond ([BLkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public synthetic fun send (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun send ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/SynchronousPortKt {
|
||||||
|
public static final fun respondStringWithDelimiter (Lspace/kscience/controls/ports/SynchronousPort;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun respondWithDelimiter (Lspace/kscience/controls/ports/SynchronousPort;[B[BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun synchronous (Lspace/kscience/controls/ports/Port;Lkotlinx/coroutines/sync/Mutex;)Lspace/kscience/controls/ports/SynchronousPort;
|
||||||
|
public static synthetic fun synchronous$default (Lspace/kscience/controls/ports/Port;Lkotlinx/coroutines/sync/Mutex;ILjava/lang/Object;)Lspace/kscience/controls/ports/SynchronousPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/TcpPort : space/kscience/controls/ports/PortFactory {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/ports/TcpPort;
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/ChannelPort;
|
||||||
|
public fun getType ()Ljava/lang/String;
|
||||||
|
public final fun open (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILkotlin/coroutines/CoroutineContext;)Lspace/kscience/controls/ports/ChannelPort;
|
||||||
|
public static synthetic fun open$default (Lspace/kscience/controls/ports/TcpPort;Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lspace/kscience/controls/ports/ChannelPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/UdpPort : space/kscience/controls/ports/PortFactory {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/ports/UdpPort;
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/ChannelPort;
|
||||||
|
public fun getType ()Ljava/lang/String;
|
||||||
|
public final fun open (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILjava/lang/Integer;Ljava/lang/String;Lkotlin/coroutines/CoroutineContext;)Lspace/kscience/controls/ports/ChannelPort;
|
||||||
|
public static synthetic fun open$default (Lspace/kscience/controls/ports/UdpPort;Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILjava/lang/Integer;Ljava/lang/String;Lkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lspace/kscience/controls/ports/ChannelPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/spec/DeviceActionSpec {
|
||||||
|
public abstract fun execute (Lspace/kscience/controls/api/Device;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public abstract fun getDescriptor ()Lspace/kscience/controls/api/ActionDescriptor;
|
||||||
|
public abstract fun getInputConverter ()Lspace/kscience/dataforge/meta/transformations/MetaConverter;
|
||||||
|
public abstract fun getOutputConverter ()Lspace/kscience/dataforge/meta/transformations/MetaConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/controls/spec/DeviceBase : space/kscience/controls/api/Device {
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun execute (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun getActionDescriptors ()Ljava/util/Collection;
|
||||||
|
public abstract fun getActions ()Ljava/util/Map;
|
||||||
|
public final fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext;
|
||||||
|
public fun getLifecycleState ()Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
public synthetic fun getMessageFlow ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public fun getMessageFlow ()Lkotlinx/coroutines/flow/SharedFlow;
|
||||||
|
public fun getMeta ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public abstract fun getProperties ()Ljava/util/Map;
|
||||||
|
public fun getProperty (Ljava/lang/String;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun getPropertyDescriptors ()Ljava/util/Collection;
|
||||||
|
public fun invalidate (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun open (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun readProperty (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun readPropertyOrNull (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
protected fun setLifecycleState (Lspace/kscience/controls/api/DeviceLifecycleState;)V
|
||||||
|
public abstract fun toString ()Ljava/lang/String;
|
||||||
|
protected final fun updateLogical (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun updateLogical (Lspace/kscience/controls/spec/DevicePropertySpec;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun writeProperty (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class space/kscience/controls/spec/DeviceBySpec : space/kscience/controls/spec/DeviceBase {
|
||||||
|
public fun <init> (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun getActions ()Ljava/util/Map;
|
||||||
|
public fun getProperties ()Ljava/util/Map;
|
||||||
|
public final fun getSpec ()Lspace/kscience/controls/spec/DeviceSpec;
|
||||||
|
public fun open (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/spec/DeviceExtensionsKt {
|
||||||
|
public static final fun doRecurring-8Mi8wO0 (Lspace/kscience/controls/api/Device;JLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
|
public static final fun readRecurring-8Mi8wO0 (Lspace/kscience/controls/api/Device;JLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/spec/DevicePropertySpec {
|
||||||
|
public abstract fun getConverter ()Lspace/kscience/dataforge/meta/transformations/MetaConverter;
|
||||||
|
public abstract fun getDescriptor ()Lspace/kscience/controls/api/PropertyDescriptor;
|
||||||
|
public abstract fun read (Lspace/kscience/controls/api/Device;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/spec/DevicePropertySpecKt {
|
||||||
|
public static final fun execute (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DeviceActionSpec;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun execute (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DeviceActionSpec;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun get (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DevicePropertySpec;)Ljava/lang/Object;
|
||||||
|
public static final fun getName (Lspace/kscience/controls/spec/DeviceActionSpec;)Ljava/lang/String;
|
||||||
|
public static final fun getName (Lspace/kscience/controls/spec/DevicePropertySpec;)Ljava/lang/String;
|
||||||
|
public static final fun invalidate (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DevicePropertySpec;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun onPropertyChange (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DevicePropertySpec;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/Job;
|
||||||
|
public static final fun propertyFlow (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DevicePropertySpec;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public static final fun read (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DevicePropertySpec;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun readOrNull (Lspace/kscience/controls/spec/DeviceBase;Lspace/kscience/controls/spec/DevicePropertySpec;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun set (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/WritableDevicePropertySpec;Ljava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
|
public static final fun useProperty (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DevicePropertySpec;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
|
public static final fun write (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/WritableDevicePropertySpec;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/controls/spec/DeviceSpec {
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun action (Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun action$default (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public final fun getActions ()Ljava/util/Map;
|
||||||
|
public final fun getProperties ()Ljava/util/Map;
|
||||||
|
public final fun metaAction (Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun metaAction$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public final fun mutableProperty (Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public final fun mutableProperty (Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/reflect/KMutableProperty1;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun mutableProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun mutableProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/reflect/KMutableProperty1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public fun onClose (Lspace/kscience/controls/api/Device;)V
|
||||||
|
public fun onOpen (Lspace/kscience/controls/api/Device;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun property (Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public final fun property (Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/reflect/KProperty1;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun property$default (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun property$default (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/reflect/KProperty1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public final fun registerAction (Lspace/kscience/controls/spec/DeviceActionSpec;)Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun registerProperty (Lspace/kscience/controls/spec/DevicePropertySpec;)Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun unitAction (Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun unitAction$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/spec/DeviceSpecKt {
|
||||||
|
public static final fun getUnit (Lspace/kscience/dataforge/meta/transformations/MetaConverter$Companion;)Lspace/kscience/dataforge/meta/transformations/MetaConverter;
|
||||||
|
public static final fun logicalProperty (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun logicalProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/spec/DurationConverter : space/kscience/dataforge/meta/transformations/MetaConverter {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/spec/DurationConverter;
|
||||||
|
public synthetic fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun metaToObject-5sfh64U (Lspace/kscience/dataforge/meta/Meta;)J
|
||||||
|
public synthetic fun objectToMeta (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun objectToMeta-LRDsOJo (J)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface annotation class space/kscience/controls/spec/InternalDeviceAPI : java/lang/annotation/Annotation {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/spec/MiscKt {
|
||||||
|
public static final fun asMeta (D)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public static final fun getDuration (Lspace/kscience/dataforge/meta/transformations/MetaConverter$Companion;)Lspace/kscience/dataforge/meta/transformations/MetaConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/spec/PropertySpecDelegatesKt {
|
||||||
|
public static final fun booleanProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun booleanProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun booleanProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun booleanProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun doubleProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun doubleProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun doubleProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun doubleProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun metaProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun metaProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun metaProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun metaProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun numberProperty (Lspace/kscience/controls/spec/DeviceSpec;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun numberProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun numberProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun numberProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun stringProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static final fun stringProperty (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun stringProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
public static synthetic fun stringProperty$default (Lspace/kscience/controls/spec/DeviceSpec;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/properties/PropertyDelegateProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/spec/UnitMetaConverter : space/kscience/dataforge/meta/transformations/MetaConverter {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/spec/UnitMetaConverter;
|
||||||
|
public synthetic fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public synthetic fun objectToMeta (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun objectToMeta (Lkotlin/Unit;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/spec/WritableDevicePropertySpec : space/kscience/controls/spec/DevicePropertySpec {
|
||||||
|
public abstract fun write (Lspace/kscience/controls/api/Device;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,14 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description = """
|
||||||
|
Core interfaces for building a device server
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
|
||||||
kscience {
|
kscience {
|
||||||
@ -22,25 +28,41 @@ kscience {
|
|||||||
|
|
||||||
|
|
||||||
readme{
|
readme{
|
||||||
|
maturity = Maturity.EXPERIMENTAL
|
||||||
|
|
||||||
feature("device", ref = "src/commonMain/kotlin/space/kscience/controls/api/Device.kt"){
|
feature("device", ref = "src/commonMain/kotlin/space/kscience/controls/api/Device.kt"){
|
||||||
"""
|
"""
|
||||||
Device API with subscription (asynchronous and pseudo-synchronous properties)
|
Device API with subscription (asynchronous and pseudo-synchronous properties)
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
readme{
|
|
||||||
feature("deviceMessage", ref = "src/commonMain/kotlin/space/kscience/controls/api/DeviceMessage.kt"){
|
feature("deviceMessage", ref = "src/commonMain/kotlin/space/kscience/controls/api/DeviceMessage.kt"){
|
||||||
"""
|
"""
|
||||||
Specification for messages used to communicate between Controls-kt devices.
|
Specification for messages used to communicate between Controls-kt devices.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
readme{
|
|
||||||
feature("deviceHub", ref = "src/commonMain/kotlin/space/kscience/controls/api/DeviceHub.kt"){
|
feature("deviceHub", ref = "src/commonMain/kotlin/space/kscience/controls/api/DeviceHub.kt"){
|
||||||
"""
|
"""
|
||||||
Grouping of devices into local tree-like hubs.
|
Grouping of devices into local tree-like hubs.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
feature("deviceSpec", ref = "src/commonMain/kotlin/space/kscience/controls/spec"){
|
||||||
|
"""
|
||||||
|
Mechanics and type-safe builders for devices. Including separation of device specification and device state.
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
feature("deviceManager", ref = "src/commonMain/kotlin/space/kscience/controls/manager"){
|
||||||
|
"""
|
||||||
|
DataForge DI integration for devices. Includes device builders.
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
feature("ports", ref = "src/commonMain/kotlin/space/kscience/controls/ports"){
|
||||||
|
"""
|
||||||
|
Working with asynchronous data sending and receiving raw byte arrays
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,10 +9,21 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import space.kscience.controls.api.Device.Companion.DEVICE_TARGET
|
import space.kscience.controls.api.Device.Companion.DEVICE_TARGET
|
||||||
import space.kscience.dataforge.context.ContextAware
|
import space.kscience.dataforge.context.ContextAware
|
||||||
|
import space.kscience.dataforge.context.info
|
||||||
|
import space.kscience.dataforge.context.logger
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.dataforge.misc.Type
|
import space.kscience.dataforge.misc.Type
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A lifecycle state of a device
|
||||||
|
*/
|
||||||
|
public enum class DeviceLifecycleState{
|
||||||
|
INIT,
|
||||||
|
OPEN,
|
||||||
|
CLOSED
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General interface describing a managed Device.
|
* General interface describing a managed Device.
|
||||||
@ -79,12 +90,16 @@ public interface Device : AutoCloseable, ContextAware, CoroutineScope {
|
|||||||
public suspend fun open(): Unit = Unit
|
public suspend fun open(): Unit = Unit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close and terminate the device. This function does not wait for device to be closed.
|
* Close and terminate the device. This function does not wait for the device to be closed.
|
||||||
*/
|
*/
|
||||||
override fun close() {
|
override fun close() {
|
||||||
|
logger.info { "Device $this is closed" }
|
||||||
cancel("The device is closed")
|
cancel("The device is closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
|
public val lifecycleState: DeviceLifecycleState
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public const val DEVICE_TARGET: String = "device"
|
public const val DEVICE_TARGET: String = "device"
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,8 @@ public interface DeviceHub : Provider {
|
|||||||
|
|
||||||
override val defaultChainTarget: String get() = Device.DEVICE_TARGET
|
override val defaultChainTarget: String get() = Device.DEVICE_TARGET
|
||||||
|
|
||||||
override fun content(target: String): Map<Name, Any> {
|
override fun content(target: String): Map<Name, Any> = if (target == Device.DEVICE_TARGET) {
|
||||||
if (target == Device.DEVICE_TARGET) {
|
buildMap {
|
||||||
return buildMap {
|
|
||||||
fun putAll(prefix: Name, hub: DeviceHub) {
|
fun putAll(prefix: Name, hub: DeviceHub) {
|
||||||
hub.devices.forEach {
|
hub.devices.forEach {
|
||||||
put(prefix + it.key, it.value)
|
put(prefix + it.key, it.value)
|
||||||
@ -32,8 +31,7 @@ public interface DeviceHub : Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw IllegalArgumentException("Target $target is not supported for $this")
|
emptyMap()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object
|
public companion object
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
|
@file:OptIn(ExperimentalSerializationApi::class)
|
||||||
|
|
||||||
package space.kscience.controls.api
|
package space.kscience.controls.api
|
||||||
|
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
|
import kotlinx.serialization.EncodeDefault
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
@ -55,9 +59,9 @@ public data class PropertyChangedMessage(
|
|||||||
override val sourceDevice: Name = Name.EMPTY,
|
override val sourceDevice: Name = Name.EMPTY,
|
||||||
override val targetDevice: Name? = null,
|
override val targetDevice: Name? = null,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,9 +75,9 @@ public data class PropertySetMessage(
|
|||||||
override val sourceDevice: Name? = null,
|
override val sourceDevice: Name? = null,
|
||||||
override val targetDevice: Name,
|
override val targetDevice: Name,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,9 +91,9 @@ public data class PropertyGetMessage(
|
|||||||
override val sourceDevice: Name? = null,
|
override val sourceDevice: Name? = null,
|
||||||
override val targetDevice: Name,
|
override val targetDevice: Name,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,9 +105,9 @@ public data class GetDescriptionMessage(
|
|||||||
override val sourceDevice: Name? = null,
|
override val sourceDevice: Name? = null,
|
||||||
override val targetDevice: Name,
|
override val targetDevice: Name,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,9 +122,9 @@ public data class DescriptionMessage(
|
|||||||
override val sourceDevice: Name,
|
override val sourceDevice: Name,
|
||||||
override val targetDevice: Name? = null,
|
override val targetDevice: Name? = null,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,9 +141,9 @@ public data class ActionExecuteMessage(
|
|||||||
override val sourceDevice: Name? = null,
|
override val sourceDevice: Name? = null,
|
||||||
override val targetDevice: Name,
|
override val targetDevice: Name,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,9 +160,9 @@ public data class ActionResultMessage(
|
|||||||
override val sourceDevice: Name,
|
override val sourceDevice: Name,
|
||||||
override val targetDevice: Name? = null,
|
override val targetDevice: Name? = null,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,9 +175,9 @@ public data class BinaryNotificationMessage(
|
|||||||
override val sourceDevice: Name,
|
override val sourceDevice: Name,
|
||||||
override val targetDevice: Name? = null,
|
override val targetDevice: Name? = null,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,9 +190,9 @@ public data class EmptyDeviceMessage(
|
|||||||
override val sourceDevice: Name? = null,
|
override val sourceDevice: Name? = null,
|
||||||
override val targetDevice: Name? = null,
|
override val targetDevice: Name? = null,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,9 +206,9 @@ public data class DeviceLogMessage(
|
|||||||
override val sourceDevice: Name? = null,
|
override val sourceDevice: Name? = null,
|
||||||
override val targetDevice: Name? = null,
|
override val targetDevice: Name? = null,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = sourceDevice?.let(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,9 +223,9 @@ public data class DeviceErrorMessage(
|
|||||||
override val sourceDevice: Name,
|
override val sourceDevice: Name,
|
||||||
override val targetDevice: Name? = null,
|
override val targetDevice: Name? = null,
|
||||||
override val comment: String? = null,
|
override val comment: String? = null,
|
||||||
override val time: Instant? = Clock.System.now()
|
@EncodeDefault override val time: Instant? = Clock.System.now(),
|
||||||
) : DeviceMessage(){
|
) : DeviceMessage() {
|
||||||
override fun changeSource(block: (Name) -> Name):DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
override fun changeSource(block: (Name) -> Name): DeviceMessage = copy(sourceDevice = block(sourceDevice))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,12 +37,7 @@ public class DeviceManager : AbstractPlugin(), DeviceHub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun <D : Device> DeviceManager.install(name: String, device: D): D {
|
||||||
/**
|
|
||||||
* Register and start a device built by [factory] with current [Context] and [meta].
|
|
||||||
*/
|
|
||||||
public fun <D : Device> DeviceManager.install(name: String, factory: Factory<D>, meta: Meta = Meta.EMPTY): D {
|
|
||||||
val device = factory(meta, context)
|
|
||||||
registerDevice(NameToken(name), device)
|
registerDevice(NameToken(name), device)
|
||||||
device.launch {
|
device.launch {
|
||||||
device.open()
|
device.open()
|
||||||
@ -50,6 +45,13 @@ public fun <D : Device> DeviceManager.install(name: String, factory: Factory<D>,
|
|||||||
return device
|
return device
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register and start a device built by [factory] with current [Context] and [meta].
|
||||||
|
*/
|
||||||
|
public fun <D : Device> DeviceManager.install(name: String, factory: Factory<D>, meta: Meta = Meta.EMPTY): D =
|
||||||
|
install(name, factory(meta, context))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A delegate that initializes device on the first use
|
* A delegate that initializes device on the first use
|
||||||
*/
|
*/
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package space.kscience.controls.misc
|
package space.kscience.controls.misc
|
||||||
|
|
||||||
|
import kotlinx.datetime.Instant
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.meta.long
|
import space.kscience.dataforge.meta.long
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
// TODO move to core
|
// TODO move to core
|
||||||
|
|
||||||
public fun Instant.toMeta(): Meta = Meta {
|
public fun Instant.toMeta(): Meta = Meta {
|
||||||
"seconds" put epochSecond
|
"seconds" put epochSeconds
|
||||||
"nanos" put nano
|
"nanos" put nanosecondsOfSecond
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Meta.instant(): Instant = value?.long?.let { Instant.ofEpochMilli(it) } ?: Instant.ofEpochSecond(
|
public fun Meta.instant(): Instant = value?.long?.let { Instant.fromEpochMilliseconds(it) } ?: Instant.fromEpochSeconds(
|
||||||
get("seconds")?.long ?: 0L,
|
get("seconds")?.long ?: 0L,
|
||||||
get("nanos")?.long ?: 0L,
|
get("nanos")?.long ?: 0L,
|
||||||
)
|
)
|
@ -18,10 +18,10 @@ public interface Port : ContextAware, Socket<ByteArray>
|
|||||||
* A specialized factory for [Port]
|
* A specialized factory for [Port]
|
||||||
*/
|
*/
|
||||||
@Type(PortFactory.TYPE)
|
@Type(PortFactory.TYPE)
|
||||||
public interface PortFactory: Factory<Port>{
|
public interface PortFactory : Factory<Port> {
|
||||||
public val type: String
|
public val type: String
|
||||||
|
|
||||||
public companion object{
|
public companion object {
|
||||||
public const val TYPE: String = "controls.port"
|
public const val TYPE: String = "controls.port"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,12 +53,10 @@ public abstract class AbstractPort(
|
|||||||
/**
|
/**
|
||||||
* Internal method to receive data synchronously
|
* Internal method to receive data synchronously
|
||||||
*/
|
*/
|
||||||
protected fun receive(data: ByteArray) {
|
protected suspend fun receive(data: ByteArray) {
|
||||||
scope.launch {
|
|
||||||
logger.debug { "${this@AbstractPort} RECEIVED: ${data.decodeToString()}" }
|
logger.debug { "${this@AbstractPort} RECEIVED: ${data.decodeToString()}" }
|
||||||
incoming.send(data)
|
incoming.send(data)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private val sendJob = scope.launch {
|
private val sendJob = scope.launch {
|
||||||
for (data in outgoing) {
|
for (data in outgoing) {
|
||||||
@ -82,7 +80,7 @@ public abstract class AbstractPort(
|
|||||||
/**
|
/**
|
||||||
* Raw flow of incoming data chunks. The chunks are not guaranteed to be complete phrases.
|
* Raw flow of incoming data chunks. The chunks are not guaranteed to be complete phrases.
|
||||||
* In order to form phrases, some condition should be used on top of it.
|
* In order to form phrases, some condition should be used on top of it.
|
||||||
* For example [delimitedIncoming] generates phrases with fixed delimiter.
|
* For example [stringsDelimitedIncoming] generates phrases with fixed delimiter.
|
||||||
*/
|
*/
|
||||||
override fun receiving(): Flow<ByteArray> = incoming.receiveAsFlow()
|
override fun receiving(): Flow<ByteArray> = incoming.receiveAsFlow()
|
||||||
|
|
||||||
|
@ -48,3 +48,8 @@ public fun Flow<ByteArray>.withStringDelimiter(delimiter: String): Flow<String>
|
|||||||
* A flow of delimited phrases
|
* A flow of delimited phrases
|
||||||
*/
|
*/
|
||||||
public fun Port.delimitedIncoming(delimiter: ByteArray): Flow<ByteArray> = receiving().withDelimiter(delimiter)
|
public fun Port.delimitedIncoming(delimiter: ByteArray): Flow<ByteArray> = receiving().withDelimiter(delimiter)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flow of delimited phrases with string content
|
||||||
|
*/
|
||||||
|
public fun Port.stringsDelimitedIncoming(delimiter: String): Flow<String> = receiving().withStringDelimiter(delimiter)
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package space.kscience.controls.spec
|
package space.kscience.controls.spec
|
||||||
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import space.kscience.controls.api.*
|
import space.kscience.controls.api.*
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.error
|
||||||
|
import space.kscience.dataforge.context.logger
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
|
||||||
@ -25,9 +26,9 @@ private suspend fun <D : Device, T> DevicePropertySpec<D, T>.readMeta(device: D)
|
|||||||
|
|
||||||
private suspend fun <D : Device, I, O> DeviceActionSpec<D, I, O>.executeWithMeta(
|
private suspend fun <D : Device, I, O> DeviceActionSpec<D, I, O>.executeWithMeta(
|
||||||
device: D,
|
device: D,
|
||||||
item: Meta?,
|
item: Meta,
|
||||||
): Meta? {
|
): Meta? {
|
||||||
val arg = item?.let { inputConverter.metaToObject(item) }
|
val arg: I = inputConverter.metaToObject(item) ?: error("Failed to convert $item with $inputConverter")
|
||||||
val res = execute(device, arg)
|
val res = execute(device, arg)
|
||||||
return res?.let { outputConverter.objectToMeta(res) }
|
return res?.let { outputConverter.objectToMeta(res) }
|
||||||
}
|
}
|
||||||
@ -37,7 +38,7 @@ private suspend fun <D : Device, I, O> DeviceActionSpec<D, I, O>.executeWithMeta
|
|||||||
* A base abstractions for [Device], introducing specifications for properties
|
* A base abstractions for [Device], introducing specifications for properties
|
||||||
*/
|
*/
|
||||||
public abstract class DeviceBase<D : Device>(
|
public abstract class DeviceBase<D : Device>(
|
||||||
override val context: Context = Global,
|
final override val context: Context,
|
||||||
override val meta: Meta = Meta.EMPTY,
|
override val meta: Meta = Meta.EMPTY,
|
||||||
) : Device {
|
) : Device {
|
||||||
|
|
||||||
@ -58,8 +59,15 @@ public abstract class DeviceBase<D : Device>(
|
|||||||
get() = actions.values.map { it.descriptor }
|
get() = actions.values.map { it.descriptor }
|
||||||
|
|
||||||
override val coroutineContext: CoroutineContext by lazy {
|
override val coroutineContext: CoroutineContext by lazy {
|
||||||
context.coroutineContext + SupervisorJob(context.coroutineContext[Job])
|
context.newCoroutineContext(
|
||||||
|
SupervisorJob(context.coroutineContext[Job]) +
|
||||||
|
CoroutineName("Device $this") +
|
||||||
|
CoroutineExceptionHandler { _, throwable ->
|
||||||
|
logger.error(throwable) { "Exception in device $this job" }
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logical state store
|
* Logical state store
|
||||||
@ -146,8 +154,26 @@ public abstract class DeviceBase<D : Device>(
|
|||||||
|
|
||||||
override suspend fun execute(actionName: String, argument: Meta?): Meta? {
|
override suspend fun execute(actionName: String, argument: Meta?): Meta? {
|
||||||
val spec = actions[actionName] ?: error("Action with name $actionName not found")
|
val spec = actions[actionName] ?: error("Action with name $actionName not found")
|
||||||
return spec.executeWithMeta(self, argument)
|
return spec.executeWithMeta(self, argument ?: Meta.EMPTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
|
override var lifecycleState: DeviceLifecycleState = DeviceLifecycleState.INIT
|
||||||
|
protected set
|
||||||
|
|
||||||
|
@OptIn(DFExperimental::class)
|
||||||
|
override suspend fun open() {
|
||||||
|
super.open()
|
||||||
|
lifecycleState = DeviceLifecycleState.OPEN
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(DFExperimental::class)
|
||||||
|
override fun close() {
|
||||||
|
lifecycleState = DeviceLifecycleState.CLOSED
|
||||||
|
super.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract override fun toString(): String
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package space.kscience.controls.spec
|
|||||||
|
|
||||||
import space.kscience.controls.api.Device
|
import space.kscience.controls.api.Device
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.Global
|
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,7 +10,7 @@ import space.kscience.dataforge.meta.Meta
|
|||||||
*/
|
*/
|
||||||
public open class DeviceBySpec<D : Device>(
|
public open class DeviceBySpec<D : Device>(
|
||||||
public val spec: DeviceSpec<in D>,
|
public val spec: DeviceSpec<in D>,
|
||||||
context: Context = Global,
|
context: Context,
|
||||||
meta: Meta = Meta.EMPTY,
|
meta: Meta = Meta.EMPTY,
|
||||||
) : DeviceBase<D>(context, meta) {
|
) : DeviceBase<D>(context, meta) {
|
||||||
override val properties: Map<String, DevicePropertySpec<D, *>> get() = spec.properties
|
override val properties: Map<String, DevicePropertySpec<D, *>> get() = spec.properties
|
||||||
@ -26,4 +25,6 @@ public open class DeviceBySpec<D : Device>(
|
|||||||
self.onClose()
|
self.onClose()
|
||||||
super.close()
|
super.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = "Device(spec=$spec)"
|
||||||
}
|
}
|
@ -2,10 +2,7 @@ package space.kscience.controls.spec
|
|||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.flow.filterIsInstance
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import space.kscience.controls.api.ActionDescriptor
|
import space.kscience.controls.api.ActionDescriptor
|
||||||
import space.kscience.controls.api.Device
|
import space.kscience.controls.api.Device
|
||||||
@ -69,7 +66,7 @@ public interface DeviceActionSpec<in D : Device, I, O> {
|
|||||||
/**
|
/**
|
||||||
* Execute action on a device
|
* Execute action on a device
|
||||||
*/
|
*/
|
||||||
public suspend fun execute(device: D, input: I?): O?
|
public suspend fun execute(device: D, input: I): O
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,19 +102,50 @@ public operator fun <T, D : Device> D.set(propertySpec: WritableDevicePropertySp
|
|||||||
write(propertySpec, value)
|
write(propertySpec, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type safe flow of property changes for given property
|
||||||
|
*/
|
||||||
|
public fun <D : Device, T> D.propertyFlow(spec: DevicePropertySpec<D, T>): Flow<T> = messageFlow
|
||||||
|
.filterIsInstance<PropertyChangedMessage>()
|
||||||
|
.filter { it.property == spec.name }
|
||||||
|
.mapNotNull { spec.converter.metaToObject(it.value) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type safe property change listener. Uses the device [CoroutineScope].
|
* A type safe property change listener. Uses the device [CoroutineScope].
|
||||||
*/
|
*/
|
||||||
public fun <D : Device, T> Device.onPropertyChange(
|
public fun <D : Device, T> D.onPropertyChange(
|
||||||
spec: DevicePropertySpec<D, T>,
|
spec: DevicePropertySpec<D, T>,
|
||||||
callback: suspend PropertyChangedMessage.(T?) -> Unit,
|
callback: suspend PropertyChangedMessage.(T) -> Unit,
|
||||||
): Job = messageFlow
|
): Job = messageFlow
|
||||||
.filterIsInstance<PropertyChangedMessage>()
|
.filterIsInstance<PropertyChangedMessage>()
|
||||||
.filter { it.property == spec.name }
|
.filter { it.property == spec.name }
|
||||||
.onEach { change ->
|
.onEach { change ->
|
||||||
change.callback(spec.converter.metaToObject(change.value))
|
val newValue = spec.converter.metaToObject(change.value)
|
||||||
|
if (newValue != null) {
|
||||||
|
change.callback(newValue)
|
||||||
|
}
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call [callback] on initial property value and each value change
|
||||||
|
*/
|
||||||
|
public fun <D : Device, T> D.useProperty(
|
||||||
|
spec: DevicePropertySpec<D, T>,
|
||||||
|
callback: suspend (T) -> Unit,
|
||||||
|
): Job = launch {
|
||||||
|
callback(read(spec))
|
||||||
|
messageFlow
|
||||||
|
.filterIsInstance<PropertyChangedMessage>()
|
||||||
|
.filter { it.property == spec.name }
|
||||||
|
.collect { change ->
|
||||||
|
val newValue = spec.converter.metaToObject(change.value)
|
||||||
|
if (newValue != null) {
|
||||||
|
callback(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the logical state of a property
|
* Reset the logical state of a property
|
||||||
*/
|
*/
|
||||||
@ -128,5 +156,8 @@ public suspend fun <D : Device> D.invalidate(propertySpec: DevicePropertySpec<D,
|
|||||||
/**
|
/**
|
||||||
* Execute the action with name according to [actionSpec]
|
* Execute the action with name according to [actionSpec]
|
||||||
*/
|
*/
|
||||||
public suspend fun <I, O, D : Device> D.execute(actionSpec: DeviceActionSpec<D, I, O>, input: I? = null): O? =
|
public suspend fun <I, O, D : Device> D.execute(actionSpec: DeviceActionSpec<D, I, O>, input: I): O =
|
||||||
actionSpec.execute(this, input)
|
actionSpec.execute(this, input)
|
||||||
|
|
||||||
|
public suspend fun <O, D : Device> D.execute(actionSpec: DeviceActionSpec<D, Unit, O>): O =
|
||||||
|
actionSpec.execute(this, Unit)
|
@ -12,6 +12,13 @@ import kotlin.reflect.KMutableProperty1
|
|||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
import kotlin.reflect.KProperty1
|
import kotlin.reflect.KProperty1
|
||||||
|
|
||||||
|
public object UnitMetaConverter: MetaConverter<Unit>{
|
||||||
|
override fun metaToObject(meta: Meta): Unit = Unit
|
||||||
|
|
||||||
|
override fun objectToMeta(obj: Unit): Meta = Meta.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
public val MetaConverter.Companion.unit: MetaConverter<Unit> get() = UnitMetaConverter
|
||||||
|
|
||||||
@OptIn(InternalDeviceAPI::class)
|
@OptIn(InternalDeviceAPI::class)
|
||||||
public abstract class DeviceSpec<D : Device> {
|
public abstract class DeviceSpec<D : Device> {
|
||||||
@ -37,25 +44,6 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
return deviceProperty
|
return deviceProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
// public fun <T> registerProperty(
|
|
||||||
// converter: MetaConverter<T>,
|
|
||||||
// readOnlyProperty: KProperty1<D, T>,
|
|
||||||
// descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
|
||||||
// ): DevicePropertySpec<D, T> {
|
|
||||||
// val deviceProperty = object : DevicePropertySpec<D, T> {
|
|
||||||
//
|
|
||||||
// override val descriptor: PropertyDescriptor = PropertyDescriptor(readOnlyProperty.name)
|
|
||||||
// .apply(descriptorBuilder)
|
|
||||||
//
|
|
||||||
// override val converter: MetaConverter<T> = converter
|
|
||||||
//
|
|
||||||
// override suspend fun read(device: D): T = withContext(device.coroutineContext) {
|
|
||||||
// readOnlyProperty.get(device)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return registerProperty(deviceProperty)
|
|
||||||
// }
|
|
||||||
|
|
||||||
public fun <T> property(
|
public fun <T> property(
|
||||||
converter: MetaConverter<T>,
|
converter: MetaConverter<T>,
|
||||||
readOnlyProperty: KProperty1<D, T>,
|
readOnlyProperty: KProperty1<D, T>,
|
||||||
@ -89,7 +77,7 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
val deviceProperty = object : WritableDevicePropertySpec<D, T> {
|
val deviceProperty = object : WritableDevicePropertySpec<D, T> {
|
||||||
|
|
||||||
override val descriptor: PropertyDescriptor = PropertyDescriptor(property.name).apply {
|
override val descriptor: PropertyDescriptor = PropertyDescriptor(property.name).apply {
|
||||||
//TODO add type from converter
|
//TODO add the type from converter
|
||||||
writable = true
|
writable = true
|
||||||
}.apply(descriptorBuilder)
|
}.apply(descriptorBuilder)
|
||||||
|
|
||||||
@ -165,7 +153,7 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
outputConverter: MetaConverter<O>,
|
outputConverter: MetaConverter<O>,
|
||||||
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
execute: suspend D.(I?) -> O?,
|
execute: suspend D.(I) -> O,
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, I, O>>> =
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, I, O>>> =
|
||||||
PropertyDelegateProvider { _: DeviceSpec<D>, property ->
|
PropertyDelegateProvider { _: DeviceSpec<D>, property ->
|
||||||
val actionName = name ?: property.name
|
val actionName = name ?: property.name
|
||||||
@ -175,7 +163,7 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
override val inputConverter: MetaConverter<I> = inputConverter
|
override val inputConverter: MetaConverter<I> = inputConverter
|
||||||
override val outputConverter: MetaConverter<O> = outputConverter
|
override val outputConverter: MetaConverter<O> = outputConverter
|
||||||
|
|
||||||
override suspend fun execute(device: D, input: I?): O? = withContext(device.coroutineContext) {
|
override suspend fun execute(device: D, input: I): O = withContext(device.coroutineContext) {
|
||||||
device.execute(input)
|
device.execute(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,7 +179,7 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
public fun metaAction(
|
public fun metaAction(
|
||||||
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
execute: suspend D.(Meta?) -> Meta?,
|
execute: suspend D.(Meta) -> Meta,
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Meta, Meta>>> =
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Meta, Meta>>> =
|
||||||
action(
|
action(
|
||||||
MetaConverter.Companion.meta,
|
MetaConverter.Companion.meta,
|
||||||
@ -209,15 +197,14 @@ public abstract class DeviceSpec<D : Device> {
|
|||||||
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
descriptorBuilder: ActionDescriptor.() -> Unit = {},
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
execute: suspend D.() -> Unit,
|
execute: suspend D.() -> Unit,
|
||||||
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Meta, Meta>>> =
|
): PropertyDelegateProvider<DeviceSpec<D>, ReadOnlyProperty<DeviceSpec<D>, DeviceActionSpec<D, Unit, Unit>>> =
|
||||||
action(
|
action(
|
||||||
MetaConverter.Companion.meta,
|
MetaConverter.Companion.unit,
|
||||||
MetaConverter.Companion.meta,
|
MetaConverter.Companion.unit,
|
||||||
descriptorBuilder,
|
descriptorBuilder,
|
||||||
name
|
name
|
||||||
) {
|
) {
|
||||||
execute()
|
execute()
|
||||||
null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,133 @@
|
|||||||
|
package space.kscience.controls.ports
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.context.error
|
||||||
|
import space.kscience.dataforge.context.info
|
||||||
|
import space.kscience.dataforge.context.logger
|
||||||
|
import space.kscience.dataforge.meta.*
|
||||||
|
import java.net.InetSocketAddress
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.channels.ByteChannel
|
||||||
|
import java.nio.channels.DatagramChannel
|
||||||
|
import java.nio.channels.SocketChannel
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
public fun ByteBuffer.toArray(limit: Int = limit()): ByteArray {
|
||||||
|
rewind()
|
||||||
|
val response = ByteArray(limit)
|
||||||
|
get(response)
|
||||||
|
rewind()
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A port based on nio [ByteChannel]
|
||||||
|
*/
|
||||||
|
public class ChannelPort(
|
||||||
|
context: Context,
|
||||||
|
coroutineContext: CoroutineContext = context.coroutineContext,
|
||||||
|
channelBuilder: suspend () -> ByteChannel,
|
||||||
|
) : AbstractPort(context, coroutineContext), AutoCloseable {
|
||||||
|
|
||||||
|
private val futureChannel: Deferred<ByteChannel> = this.scope.async(Dispatchers.IO) {
|
||||||
|
channelBuilder()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler to await port connection
|
||||||
|
*/
|
||||||
|
public val startJob: Job get() = futureChannel
|
||||||
|
|
||||||
|
private val listenerJob = this.scope.launch(Dispatchers.IO) {
|
||||||
|
val channel = futureChannel.await()
|
||||||
|
val buffer = ByteBuffer.allocate(1024)
|
||||||
|
while (isActive) {
|
||||||
|
try {
|
||||||
|
val num = channel.read(buffer)
|
||||||
|
if (num > 0) {
|
||||||
|
receive(buffer.toArray(num))
|
||||||
|
}
|
||||||
|
if (num < 0) cancel("The input channel is exhausted")
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
logger.error(ex) { "Channel read error" }
|
||||||
|
delay(1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun write(data: ByteArray): Unit = withContext(Dispatchers.IO) {
|
||||||
|
futureChannel.await().write(ByteBuffer.wrap(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
override fun close() {
|
||||||
|
listenerJob.cancel()
|
||||||
|
if (futureChannel.isCompleted) {
|
||||||
|
futureChannel.getCompleted().close()
|
||||||
|
} else {
|
||||||
|
futureChannel.cancel()
|
||||||
|
}
|
||||||
|
super.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [PortFactory] for TCP connections
|
||||||
|
*/
|
||||||
|
public object TcpPort : PortFactory {
|
||||||
|
|
||||||
|
override val type: String = "tcp"
|
||||||
|
|
||||||
|
public fun open(
|
||||||
|
context: Context,
|
||||||
|
host: String,
|
||||||
|
port: Int,
|
||||||
|
coroutineContext: CoroutineContext = context.coroutineContext,
|
||||||
|
): ChannelPort = ChannelPort(context, coroutineContext) {
|
||||||
|
SocketChannel.open(InetSocketAddress(host, port))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(context: Context, meta: Meta): ChannelPort {
|
||||||
|
val host = meta["host"].string ?: "localhost"
|
||||||
|
val port = meta["port"].int ?: error("Port value for TCP port is not defined in $meta")
|
||||||
|
return open(context, host, port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [PortFactory] for UDP connections
|
||||||
|
*/
|
||||||
|
public object UdpPort : PortFactory {
|
||||||
|
|
||||||
|
override val type: String = "udp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect a datagram channel to a remote host/port. If [localPort] is provided, it is used to bind local port for receiving messages.
|
||||||
|
*/
|
||||||
|
public fun open(
|
||||||
|
context: Context,
|
||||||
|
remoteHost: String,
|
||||||
|
remotePort: Int,
|
||||||
|
localPort: Int? = null,
|
||||||
|
localHost: String = "localhost",
|
||||||
|
coroutineContext: CoroutineContext = context.coroutineContext,
|
||||||
|
): ChannelPort = ChannelPort(context, coroutineContext) {
|
||||||
|
DatagramChannel.open().apply {
|
||||||
|
//bind the channel to a local port to receive messages
|
||||||
|
localPort?.let { bind(InetSocketAddress(localHost, localPort)) }
|
||||||
|
//connect to remote port to send messages
|
||||||
|
connect(InetSocketAddress(remoteHost, remotePort))
|
||||||
|
context.logger.info { "Connected to UDP $remotePort on $remoteHost" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(context: Context, meta: Meta): ChannelPort {
|
||||||
|
val remoteHost by meta.string { error("Remote host is not specified") }
|
||||||
|
val remotePort by meta.number { error("Remote port is not specified") }
|
||||||
|
val localHost: String? by meta.string()
|
||||||
|
val localPort: Int? by meta.int()
|
||||||
|
return open(context, remoteHost, remotePort.toInt(), localPort, localHost ?: "localhost")
|
||||||
|
}
|
||||||
|
}
|
@ -6,21 +6,29 @@ import space.kscience.dataforge.context.PluginFactory
|
|||||||
import space.kscience.dataforge.context.PluginTag
|
import space.kscience.dataforge.context.PluginTag
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.parseAsName
|
||||||
|
|
||||||
public class TcpPortPlugin : AbstractPlugin() {
|
/**
|
||||||
|
* A plugin for loading JVM nio-based ports
|
||||||
|
*/
|
||||||
|
public class JvmPortsPlugin : AbstractPlugin() {
|
||||||
|
public val ports: Ports by require(Ports)
|
||||||
|
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
override fun content(target: String): Map<Name, Any> = when(target){
|
override fun content(target: String): Map<Name, Any> = when(target){
|
||||||
PortFactory.TYPE -> mapOf(Name.EMPTY to TcpPort)
|
PortFactory.TYPE -> mapOf(
|
||||||
|
TcpPort.type.parseAsName() to TcpPort,
|
||||||
|
UdpPort.type.parseAsName() to UdpPort
|
||||||
|
)
|
||||||
else -> emptyMap()
|
else -> emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object : PluginFactory<TcpPortPlugin> {
|
public companion object : PluginFactory<JvmPortsPlugin> {
|
||||||
|
|
||||||
override val tag: PluginTag = PluginTag("controls.ports.tcp", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag("controls.ports.jvm", group = PluginTag.DATAFORGE_GROUP)
|
||||||
|
|
||||||
override fun build(context: Context, meta: Meta): TcpPortPlugin = TcpPortPlugin()
|
override fun build(context: Context, meta: Meta): JvmPortsPlugin = JvmPortsPlugin()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,95 +0,0 @@
|
|||||||
package space.kscience.controls.ports
|
|
||||||
|
|
||||||
import kotlinx.coroutines.*
|
|
||||||
import space.kscience.dataforge.context.Context
|
|
||||||
import space.kscience.dataforge.context.error
|
|
||||||
import space.kscience.dataforge.context.logger
|
|
||||||
import space.kscience.dataforge.meta.Meta
|
|
||||||
import space.kscience.dataforge.meta.get
|
|
||||||
import space.kscience.dataforge.meta.int
|
|
||||||
import space.kscience.dataforge.meta.string
|
|
||||||
import java.net.InetSocketAddress
|
|
||||||
import java.nio.ByteBuffer
|
|
||||||
import java.nio.channels.SocketChannel
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
internal fun ByteBuffer.readArray(limit: Int = limit()): ByteArray {
|
|
||||||
rewind()
|
|
||||||
val response = ByteArray(limit)
|
|
||||||
get(response)
|
|
||||||
rewind()
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TcpPort private constructor(
|
|
||||||
context: Context,
|
|
||||||
public val host: String,
|
|
||||||
public val port: Int,
|
|
||||||
coroutineContext: CoroutineContext = context.coroutineContext,
|
|
||||||
) : AbstractPort(context, coroutineContext), AutoCloseable {
|
|
||||||
|
|
||||||
override fun toString(): String = "port[tcp:$host:$port]"
|
|
||||||
|
|
||||||
private val futureChannel: Deferred<SocketChannel> = this.scope.async(Dispatchers.IO) {
|
|
||||||
SocketChannel.open(InetSocketAddress(host, port)).apply {
|
|
||||||
configureBlocking(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A handler to await port connection
|
|
||||||
*/
|
|
||||||
public val startJob: Job get() = futureChannel
|
|
||||||
|
|
||||||
private val listenerJob = this.scope.launch(Dispatchers.IO) {
|
|
||||||
val channel = futureChannel.await()
|
|
||||||
val buffer = ByteBuffer.allocate(1024)
|
|
||||||
while (isActive) {
|
|
||||||
try {
|
|
||||||
val num = channel.read(buffer)
|
|
||||||
if (num > 0) {
|
|
||||||
receive(buffer.readArray(num))
|
|
||||||
}
|
|
||||||
if (num < 0) cancel("The input channel is exhausted")
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
logger.error(ex) { "Channel read error" }
|
|
||||||
delay(1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun write(data: ByteArray): Unit = withContext(Dispatchers.IO){
|
|
||||||
futureChannel.await().write(ByteBuffer.wrap(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
|
||||||
override fun close() {
|
|
||||||
listenerJob.cancel()
|
|
||||||
if (futureChannel.isCompleted) {
|
|
||||||
futureChannel.getCompleted().close()
|
|
||||||
} else {
|
|
||||||
futureChannel.cancel()
|
|
||||||
}
|
|
||||||
super.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
public companion object : PortFactory {
|
|
||||||
|
|
||||||
override val type: String = "tcp"
|
|
||||||
|
|
||||||
public fun open(
|
|
||||||
context: Context,
|
|
||||||
host: String,
|
|
||||||
port: Int,
|
|
||||||
coroutineContext: CoroutineContext = context.coroutineContext,
|
|
||||||
): TcpPort {
|
|
||||||
return TcpPort(context, host, port, coroutineContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun build(context: Context, meta: Meta): Port {
|
|
||||||
val host = meta["host"].string ?: "localhost"
|
|
||||||
val port = meta["port"].int ?: error("Port value for TCP port is not defined in $meta")
|
|
||||||
return open(context, host, port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
# Module controls-ktor-tcp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id("space.kscience.gradle.jvm")
|
|
||||||
}
|
|
||||||
|
|
||||||
val ktorVersion: String by rootProject.extra
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
api(projects.controlsCore)
|
|
||||||
api("io.ktor:ktor-network:$ktorVersion")
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
# Module controls-magix-client
|
|
||||||
|
|
||||||
Magix service for binding controls devices (both as RPC client and server
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
## Artifact:
|
|
||||||
|
|
||||||
The Maven coordinates of this project are `space.kscience:controls-magix-client:0.1.1-SNAPSHOT`.
|
|
||||||
|
|
||||||
**Gradle Groovy:**
|
|
||||||
```groovy
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://repo.kotlin.link' }
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'space.kscience:controls-magix-client:0.1.1-SNAPSHOT'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Gradle Kotlin DSL:**
|
|
||||||
```kotlin
|
|
||||||
repositories {
|
|
||||||
maven("https://repo.kotlin.link")
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation("space.kscience:controls-magix-client:0.1.1-SNAPSHOT")
|
|
||||||
}
|
|
||||||
```
|
|
29
controls-magix/README.md
Normal file
29
controls-magix/README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Module controls-magix
|
||||||
|
|
||||||
|
Magix service for binding controls devices (both as RPC client and server)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [controlsMagix](src/commonMain/kotlin/space/kscience/controls/client/controlsMagix.kt) : Connect a `DeviceManage` with one or many devices to the Magix endpoint
|
||||||
|
- [DeviceClient](src/commonMain/kotlin/space/kscience/controls/client/DeviceClient.kt) : A remote connector to Controls-kt device via Magix
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## Artifact:
|
||||||
|
|
||||||
|
The Maven coordinates of this project are `space.kscience:controls-magix:0.2.0`.
|
||||||
|
|
||||||
|
**Gradle Kotlin DSL:**
|
||||||
|
```kotlin
|
||||||
|
repositories {
|
||||||
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("space.kscience:controls-magix:0.2.0")
|
||||||
|
}
|
||||||
|
```
|
199
controls-magix/api/controls-magix.api
Normal file
199
controls-magix/api/controls-magix.api
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
public final class space/kscience/controls/client/ControlsMagixKt {
|
||||||
|
public static final fun getMagixFormat (Lspace/kscience/controls/manager/DeviceManager$Companion;)Lspace/kscience/magix/api/MagixFormat;
|
||||||
|
public static final fun launchMagixService (Lspace/kscience/controls/manager/DeviceManager;Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;)Lkotlinx/coroutines/Job;
|
||||||
|
public static synthetic fun launchMagixService$default (Lspace/kscience/controls/manager/DeviceManager;Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/DeviceClient : space/kscience/controls/api/Device {
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/names/Name;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)V
|
||||||
|
public fun execute (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun getActionDescriptors ()Ljava/util/Collection;
|
||||||
|
public fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext;
|
||||||
|
public fun getLifecycleState ()Lspace/kscience/controls/api/DeviceLifecycleState;
|
||||||
|
public fun getMessageFlow ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public fun getProperty (Ljava/lang/String;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun getPropertyDescriptors ()Ljava/util/Collection;
|
||||||
|
public fun invalidate (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun readProperty (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun writeProperty (Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/DeviceClientKt {
|
||||||
|
public static final fun remoteDevice (Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/dataforge/context/Context;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/controls/client/DeviceClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/DoocsAction : java/lang/Enum {
|
||||||
|
public static final field Companion Lspace/kscience/controls/client/DoocsAction$Companion;
|
||||||
|
public static final field get Lspace/kscience/controls/client/DoocsAction;
|
||||||
|
public static final field names Lspace/kscience/controls/client/DoocsAction;
|
||||||
|
public static final field set Lspace/kscience/controls/client/DoocsAction;
|
||||||
|
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||||
|
public static fun valueOf (Ljava/lang/String;)Lspace/kscience/controls/client/DoocsAction;
|
||||||
|
public static fun values ()[Lspace/kscience/controls/client/DoocsAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/DoocsAction$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/DoocsPayload {
|
||||||
|
public static final field Companion Lspace/kscience/controls/client/DoocsPayload$Companion;
|
||||||
|
public synthetic fun <init> (ILspace/kscience/controls/client/DoocsAction;Ljava/lang/String;Lspace/kscience/controls/client/EqData;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Lspace/kscience/controls/client/DoocsAction;Ljava/lang/String;Lspace/kscience/controls/client/EqData;)V
|
||||||
|
public final fun component1 ()Lspace/kscience/controls/client/DoocsAction;
|
||||||
|
public final fun component2 ()Ljava/lang/String;
|
||||||
|
public final fun component3 ()Lspace/kscience/controls/client/EqData;
|
||||||
|
public final fun copy (Lspace/kscience/controls/client/DoocsAction;Ljava/lang/String;Lspace/kscience/controls/client/EqData;)Lspace/kscience/controls/client/DoocsPayload;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/client/DoocsPayload;Lspace/kscience/controls/client/DoocsAction;Ljava/lang/String;Lspace/kscience/controls/client/EqData;ILjava/lang/Object;)Lspace/kscience/controls/client/DoocsPayload;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getAction ()Lspace/kscience/controls/client/DoocsAction;
|
||||||
|
public final fun getAddress ()Ljava/lang/String;
|
||||||
|
public final fun getData ()Lspace/kscience/controls/client/EqData;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/client/DoocsPayload;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/DoocsPayload$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/client/DoocsPayload$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/client/DoocsPayload;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/client/DoocsPayload;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/DoocsPayload$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/EqData {
|
||||||
|
public static final field Companion Lspace/kscience/controls/client/EqData$Companion;
|
||||||
|
public synthetic fun <init> (IILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;Ljava/lang/String;)V
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun component1 ()I
|
||||||
|
public final fun component2 ()Ljava/lang/String;
|
||||||
|
public final fun component3 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component4 ()Ljava/lang/Integer;
|
||||||
|
public final fun component5 ()Ljava/lang/Integer;
|
||||||
|
public final fun component6 ()Ljava/lang/Long;
|
||||||
|
public final fun component7 ()Ljava/lang/String;
|
||||||
|
public final fun copy (ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;Ljava/lang/String;)Lspace/kscience/controls/client/EqData;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/client/EqData;ILjava/lang/String;Lspace/kscience/dataforge/meta/Meta;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;Ljava/lang/String;ILjava/lang/Object;)Lspace/kscience/controls/client/EqData;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getError ()Ljava/lang/Integer;
|
||||||
|
public final fun getEventId ()Ljava/lang/Integer;
|
||||||
|
public final fun getMessage ()Ljava/lang/String;
|
||||||
|
public final fun getTime ()Ljava/lang/Long;
|
||||||
|
public final fun getType ()Ljava/lang/String;
|
||||||
|
public final fun getTypeId ()I
|
||||||
|
public final fun getValue ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/client/EqData;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/EqData$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/client/EqData$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/client/EqData;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/client/EqData;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/EqData$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoAction : java/lang/Enum {
|
||||||
|
public static final field Companion Lspace/kscience/controls/client/TangoAction$Companion;
|
||||||
|
public static final field exec Lspace/kscience/controls/client/TangoAction;
|
||||||
|
public static final field pipe Lspace/kscience/controls/client/TangoAction;
|
||||||
|
public static final field read Lspace/kscience/controls/client/TangoAction;
|
||||||
|
public static final field write Lspace/kscience/controls/client/TangoAction;
|
||||||
|
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||||
|
public static fun valueOf (Ljava/lang/String;)Lspace/kscience/controls/client/TangoAction;
|
||||||
|
public static fun values ()[Lspace/kscience/controls/client/TangoAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoAction$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoMagixKt {
|
||||||
|
public static final field TANGO_MAGIX_FORMAT Ljava/lang/String;
|
||||||
|
public static final fun launchTangoMagix (Lspace/kscience/controls/manager/DeviceManager;Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;)Lkotlinx/coroutines/Job;
|
||||||
|
public static synthetic fun launchTangoMagix$default (Lspace/kscience/controls/manager/DeviceManager;Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoPayload {
|
||||||
|
public static final field Companion Lspace/kscience/controls/client/TangoPayload$Companion;
|
||||||
|
public synthetic fun <init> (ILspace/kscience/controls/client/TangoAction;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/controls/client/TangoQuality;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Lspace/kscience/controls/client/TangoAction;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/controls/client/TangoQuality;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Ljava/util/List;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/controls/client/TangoAction;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/controls/client/TangoQuality;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun component1 ()Lspace/kscience/controls/client/TangoAction;
|
||||||
|
public final fun component10 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component11 ()Ljava/util/List;
|
||||||
|
public final fun component2 ()I
|
||||||
|
public final fun component3 ()Ljava/lang/String;
|
||||||
|
public final fun component4 ()Ljava/lang/String;
|
||||||
|
public final fun component5 ()Ljava/lang/String;
|
||||||
|
public final fun component6 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component7 ()Lspace/kscience/controls/client/TangoQuality;
|
||||||
|
public final fun component8 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun component9 ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun copy (Lspace/kscience/controls/client/TangoAction;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/controls/client/TangoQuality;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Ljava/util/List;)Lspace/kscience/controls/client/TangoPayload;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/client/TangoPayload;Lspace/kscience/controls/client/TangoAction;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/controls/client/TangoQuality;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;Ljava/util/List;ILjava/lang/Object;)Lspace/kscience/controls/client/TangoPayload;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getAction ()Lspace/kscience/controls/client/TangoAction;
|
||||||
|
public final fun getArgin ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun getArgout ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun getData ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public final fun getDevice ()Ljava/lang/String;
|
||||||
|
public final fun getErrors ()Ljava/util/List;
|
||||||
|
public final fun getHost ()Ljava/lang/String;
|
||||||
|
public final fun getName ()Ljava/lang/String;
|
||||||
|
public final fun getQuality ()Lspace/kscience/controls/client/TangoQuality;
|
||||||
|
public final fun getTimestamp ()I
|
||||||
|
public final fun getValue ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/controls/client/TangoPayload;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoPayload$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/controls/client/TangoPayload$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/controls/client/TangoPayload;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/controls/client/TangoPayload;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoPayload$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoQuality : java/lang/Enum {
|
||||||
|
public static final field ALARM Lspace/kscience/controls/client/TangoQuality;
|
||||||
|
public static final field Companion Lspace/kscience/controls/client/TangoQuality$Companion;
|
||||||
|
public static final field VALID Lspace/kscience/controls/client/TangoQuality;
|
||||||
|
public static final field WARNING Lspace/kscience/controls/client/TangoQuality;
|
||||||
|
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||||
|
public static fun valueOf (Ljava/lang/String;)Lspace/kscience/controls/client/TangoQuality;
|
||||||
|
public static fun values ()[Lspace/kscience/controls/client/TangoQuality;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/client/TangoQuality$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
39
controls-magix/build.gradle.kts
Normal file
39
controls-magix/build.gradle.kts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("space.kscience.gradle.mpp")
|
||||||
|
`maven-publish`
|
||||||
|
}
|
||||||
|
|
||||||
|
description = """
|
||||||
|
Magix service for binding controls devices (both as RPC client and server)
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
kscience {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
useSerialization {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
api(projects.magix.magixApi)
|
||||||
|
api(projects.controlsCore)
|
||||||
|
api("com.benasher44:uuid:0.8.0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readme {
|
||||||
|
maturity = Maturity.EXPERIMENTAL
|
||||||
|
|
||||||
|
feature("controlsMagix", ref = "src/commonMain/kotlin/space/kscience/controls/client/controlsMagix.kt"){
|
||||||
|
"""
|
||||||
|
Connect a `DeviceManage` with one or many devices to the Magix endpoint
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
feature("DeviceClient", ref = "src/commonMain/kotlin/space/kscience/controls/client/DeviceClient.kt"){
|
||||||
|
"""
|
||||||
|
A remote connector to Controls-kt device via Magix
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
}
|
@ -6,18 +6,20 @@ import kotlinx.coroutines.newCoroutineContext
|
|||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import space.kscience.controls.api.*
|
import space.kscience.controls.api.*
|
||||||
|
import space.kscience.controls.manager.DeviceManager
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.magix.api.MagixEndpoint
|
import space.kscience.magix.api.MagixEndpoint
|
||||||
import space.kscience.magix.api.broadcast
|
import space.kscience.magix.api.send
|
||||||
import space.kscience.magix.api.subscribe
|
import space.kscience.magix.api.subscribe
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
private fun stringUID() = uuid4().leastSignificantBits.toString(16)
|
private fun stringUID() = uuid4().leastSignificantBits.toString(16)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of device via RPC
|
* A remote accessible device that relies on connection via Magix
|
||||||
*/
|
*/
|
||||||
public class DeviceClient(
|
public class DeviceClient(
|
||||||
override val context: Context,
|
override val context: Context,
|
||||||
@ -95,14 +97,21 @@ public class DeviceClient(
|
|||||||
it.action == actionName && it.requestId == id
|
it.action == actionName && it.requestId == id
|
||||||
}.result
|
}.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
|
override val lifecycleState: DeviceLifecycleState = DeviceLifecycleState.OPEN
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to a remote device via this client.
|
* Connect to a remote device via this endpoint.
|
||||||
|
*
|
||||||
|
* @param context a [Context] to run device in
|
||||||
|
* @param endpointName the name of endpoint in Magix to connect to
|
||||||
|
* @param deviceName the name of device within endpoint
|
||||||
*/
|
*/
|
||||||
public fun MagixEndpoint.remoteDevice(context: Context, magixTarget: String, deviceName: Name): DeviceClient {
|
public fun MagixEndpoint.remoteDevice(context: Context, endpointName: String, deviceName: Name): DeviceClient {
|
||||||
val subscription = subscribe(controlsMagixFormat, originFilter = listOf(magixTarget)).map { it.second }
|
val subscription = subscribe(DeviceManager.magixFormat, originFilter = listOf(endpointName)).map { it.second }
|
||||||
return DeviceClient(context, deviceName, subscription) {
|
return DeviceClient(context, deviceName, subscription) {
|
||||||
broadcast(controlsMagixFormat, it, magixTarget, id = stringUID())
|
send(DeviceManager.magixFormat, it, endpointName, id = stringUID())
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,31 +14,37 @@ import space.kscience.dataforge.context.logger
|
|||||||
import space.kscience.magix.api.*
|
import space.kscience.magix.api.*
|
||||||
|
|
||||||
|
|
||||||
public val controlsMagixFormat: MagixFormat<DeviceMessage> = MagixFormat(
|
internal val controlsMagixFormat: MagixFormat<DeviceMessage> = MagixFormat(
|
||||||
DeviceMessage.serializer(),
|
DeviceMessage.serializer(),
|
||||||
setOf("controls-kt", "dataforge")
|
setOf("controls-kt")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A magix message format to work with Controls-kt data
|
||||||
|
*/
|
||||||
|
public val DeviceManager.Companion.magixFormat: MagixFormat<DeviceMessage> get() = controlsMagixFormat
|
||||||
|
|
||||||
internal fun generateId(request: MagixMessage): String = if (request.id != null) {
|
internal fun generateId(request: MagixMessage): String = if (request.id != null) {
|
||||||
"${request.id}.response"
|
"${request.id}.response"
|
||||||
} else {
|
} else {
|
||||||
"df[${request.payload.hashCode()}"
|
"controls[${request.payload.hashCode().toString(16)}"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1)
|
* Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1)
|
||||||
*/
|
*/
|
||||||
public fun DeviceManager.connectToMagix(
|
public fun DeviceManager.launchMagixService(
|
||||||
endpoint: MagixEndpoint,
|
endpoint: MagixEndpoint,
|
||||||
endpointID: String = controlsMagixFormat.defaultFormat,
|
endpointID: String = controlsMagixFormat.defaultFormat,
|
||||||
): Job = context.launch {
|
): Job = context.launch {
|
||||||
endpoint.subscribe(controlsMagixFormat, targetFilter = listOf(endpointID)).onEach { (request, payload) ->
|
endpoint.subscribe(controlsMagixFormat, targetFilter = listOf(endpointID)).onEach { (request, payload) ->
|
||||||
val responsePayload = respondHubMessage(payload)
|
val responsePayload = respondHubMessage(payload)
|
||||||
if (responsePayload != null) {
|
if (responsePayload != null) {
|
||||||
endpoint.broadcast(
|
endpoint.send(
|
||||||
format = controlsMagixFormat,
|
format = controlsMagixFormat,
|
||||||
origin = endpointID,
|
|
||||||
payload = responsePayload,
|
payload = responsePayload,
|
||||||
|
source = endpointID,
|
||||||
|
target = request.sourceEndpoint,
|
||||||
id = generateId(request),
|
id = generateId(request),
|
||||||
parentId = request.id
|
parentId = request.id
|
||||||
)
|
)
|
||||||
@ -48,10 +54,10 @@ public fun DeviceManager.connectToMagix(
|
|||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
|
|
||||||
hubMessageFlow(this).onEach { payload ->
|
hubMessageFlow(this).onEach { payload ->
|
||||||
endpoint.broadcast(
|
endpoint.send(
|
||||||
format = controlsMagixFormat,
|
format = controlsMagixFormat,
|
||||||
origin = endpointID,
|
|
||||||
payload = payload,
|
payload = payload,
|
||||||
|
source = endpointID,
|
||||||
id = "df[${payload.hashCode()}]"
|
id = "df[${payload.hashCode()}]"
|
||||||
)
|
)
|
||||||
}.catch { error ->
|
}.catch { error ->
|
@ -75,12 +75,12 @@ public fun DeviceManager.launchTangoMagix(
|
|||||||
): Job {
|
): Job {
|
||||||
|
|
||||||
suspend fun respond(request: MagixMessage, payload: TangoPayload, payloadBuilder: (TangoPayload) -> TangoPayload) {
|
suspend fun respond(request: MagixMessage, payload: TangoPayload, payloadBuilder: (TangoPayload) -> TangoPayload) {
|
||||||
endpoint.broadcast(
|
endpoint.send(
|
||||||
tangoMagixFormat,
|
tangoMagixFormat,
|
||||||
|
payload = payloadBuilder(payload),
|
||||||
|
source = endpointID,
|
||||||
id = generateId(request),
|
id = generateId(request),
|
||||||
parentId = request.id,
|
parentId = request.id
|
||||||
origin = endpointID,
|
|
||||||
payload = payloadBuilder(payload)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,12 +125,12 @@ public fun DeviceManager.launchTangoMagix(
|
|||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
logger.error(ex) { "Error while responding to message" }
|
logger.error(ex) { "Error while responding to message" }
|
||||||
endpoint.broadcast(
|
endpoint.send(
|
||||||
tangoMagixFormat,
|
tangoMagixFormat,
|
||||||
|
payload = payload.copy(quality = TangoQuality.WARNING),
|
||||||
|
source = endpointID,
|
||||||
id = generateId(request),
|
id = generateId(request),
|
||||||
parentId = request.id,
|
parentId = request.id
|
||||||
origin = endpointID,
|
|
||||||
payload = payload.copy(quality = TangoQuality.WARNING)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
@ -2,3 +2,30 @@
|
|||||||
|
|
||||||
A plugin for Controls-kt device server on top of modbus-rtu/modbus-tcp protocols
|
A plugin for Controls-kt device server on top of modbus-rtu/modbus-tcp protocols
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [modbusRegistryMap](src/main/kotlin/space/kscience/controls/modbus/ModbusRegistryMap.kt) : Type-safe modbus registry map. Allows to define both single-register and multi-register entries (using DataForge IO).
|
||||||
|
Automatically checks consistency.
|
||||||
|
- [modbusProcessImage](src/main/kotlin/space/kscience/controls/modbus/DeviceProcessImage.kt) : Binding of slave (server) modbus device to Controls-kt device
|
||||||
|
- [modbusDevice](src/main/kotlin/space/kscience/controls/modbus/ModbusDevice.kt) : A device with additional methods to work with modbus registers.
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## Artifact:
|
||||||
|
|
||||||
|
The Maven coordinates of this project are `space.kscience:controls-modbus:0.2.0`.
|
||||||
|
|
||||||
|
**Gradle Kotlin DSL:**
|
||||||
|
```kotlin
|
||||||
|
repositories {
|
||||||
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("space.kscience:controls-modbus:0.2.0")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
166
controls-modbus/api/controls-modbus.api
Normal file
166
controls-modbus/api/controls-modbus.api
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
public final class space/kscience/controls/modbus/DeviceProcessImageBuilder {
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;Lkotlin/jvm/functions/Function2;)Lcom/ghgande/j2mod/modbus/procimg/ObservableDigitalOut;
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;Lspace/kscience/controls/spec/WritableDevicePropertySpec;)Lcom/ghgande/j2mod/modbus/procimg/ObservableDigitalOut;
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;Lkotlin/jvm/functions/Function2;)Lcom/ghgande/j2mod/modbus/procimg/DigitalIn;
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;Lspace/kscience/controls/spec/DevicePropertySpec;)Lcom/ghgande/j2mod/modbus/procimg/DigitalIn;
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRange;Lspace/kscience/controls/spec/WritableDevicePropertySpec;)V
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;Lkotlin/jvm/functions/Function2;)Lcom/ghgande/j2mod/modbus/procimg/ObservableRegister;
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;Lspace/kscience/controls/spec/WritableDevicePropertySpec;)Lcom/ghgande/j2mod/modbus/procimg/ObservableRegister;
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRange;Lspace/kscience/controls/spec/DevicePropertySpec;)V
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRegister;Lkotlin/jvm/functions/Function2;)Lcom/ghgande/j2mod/modbus/procimg/SimpleInputRegister;
|
||||||
|
public final fun bind (Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRegister;Lspace/kscience/controls/spec/DevicePropertySpec;)Lcom/ghgande/j2mod/modbus/procimg/SimpleInputRegister;
|
||||||
|
public static synthetic fun bind$default (Lspace/kscience/controls/modbus/DeviceProcessImageBuilder;Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/ghgande/j2mod/modbus/procimg/ObservableDigitalOut;
|
||||||
|
public static synthetic fun bind$default (Lspace/kscience/controls/modbus/DeviceProcessImageBuilder;Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/ghgande/j2mod/modbus/procimg/DigitalIn;
|
||||||
|
public static synthetic fun bind$default (Lspace/kscience/controls/modbus/DeviceProcessImageBuilder;Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/ghgande/j2mod/modbus/procimg/ObservableRegister;
|
||||||
|
public static synthetic fun bind$default (Lspace/kscience/controls/modbus/DeviceProcessImageBuilder;Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRegister;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/ghgande/j2mod/modbus/procimg/SimpleInputRegister;
|
||||||
|
public final fun bindAction (Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;Lkotlin/jvm/functions/Function3;)Lcom/ghgande/j2mod/modbus/procimg/ObservableDigitalOut;
|
||||||
|
public final fun bindAction (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRange;Lkotlin/jvm/functions/Function3;)Ljava/util/List;
|
||||||
|
public final fun bindAction (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;Lkotlin/jvm/functions/Function3;)Lcom/ghgande/j2mod/modbus/procimg/ObservableRegister;
|
||||||
|
public final fun getImage ()Lcom/ghgande/j2mod/modbus/procimg/ProcessImageImplementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/DeviceProcessImageKt {
|
||||||
|
public static final fun bindProcessImage (Lspace/kscience/controls/api/Device;ZLkotlin/jvm/functions/Function1;)Lcom/ghgande/j2mod/modbus/procimg/ProcessImage;
|
||||||
|
public static synthetic fun bindProcessImage$default (Lspace/kscience/controls/api/Device;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/ghgande/j2mod/modbus/procimg/ProcessImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/modbus/ModbusDevice : space/kscience/controls/api/Device {
|
||||||
|
public abstract fun getClientId ()I
|
||||||
|
public abstract fun getMaster ()Lcom/ghgande/j2mod/modbus/facade/AbstractModbusMaster;
|
||||||
|
public fun getValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Z
|
||||||
|
public fun getValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Z
|
||||||
|
public fun getValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRange;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
|
||||||
|
public fun getValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;Ljava/lang/Object;Lkotlin/reflect/KProperty;)S
|
||||||
|
public fun getValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRange;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
|
||||||
|
public fun getValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRegister;Ljava/lang/Object;Lkotlin/reflect/KProperty;)S
|
||||||
|
public fun setValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;Ljava/lang/Object;Lkotlin/reflect/KProperty;Z)V
|
||||||
|
public fun setValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRange;Ljava/lang/Object;Lkotlin/reflect/KProperty;Ljava/lang/Object;)V
|
||||||
|
public fun setValue (Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;Ljava/lang/Object;Lkotlin/reflect/KProperty;S)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public class space/kscience/controls/modbus/ModbusDeviceBySpec : space/kscience/controls/spec/DeviceBySpec, space/kscience/controls/modbus/ModbusDevice {
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/controls/spec/DeviceSpec;ILcom/ghgande/j2mod/modbus/facade/AbstractModbusMaster;ZLspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/controls/spec/DeviceSpec;ILcom/ghgande/j2mod/modbus/facade/AbstractModbusMaster;ZLspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun getClientId ()I
|
||||||
|
public fun getMaster ()Lcom/ghgande/j2mod/modbus/facade/AbstractModbusMaster;
|
||||||
|
public fun open (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/ModbusDeviceKt {
|
||||||
|
public static final fun modbusDoubleRegister (Lspace/kscience/controls/modbus/ModbusDevice;I)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
public static final fun modbusRegister (Lspace/kscience/controls/modbus/ModbusDevice;I)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
public static final fun readCoil (Lspace/kscience/controls/modbus/ModbusDevice;I)Z
|
||||||
|
public static final fun readCoils (Lspace/kscience/controls/modbus/ModbusDevice;II)Lcom/ghgande/j2mod/modbus/util/BitVector;
|
||||||
|
public static final fun readDoubleInput (Lspace/kscience/controls/modbus/ModbusDevice;I)D
|
||||||
|
public static final fun readDoubleRegister (Lspace/kscience/controls/modbus/ModbusDevice;I)D
|
||||||
|
public static final fun readHoldingRegister (Lspace/kscience/controls/modbus/ModbusDevice;I)S
|
||||||
|
public static final fun readHoldingRegisters (Lspace/kscience/controls/modbus/ModbusDevice;II)Ljava/util/List;
|
||||||
|
public static final fun readHoldingRegistersToBuffer (Lspace/kscience/controls/modbus/ModbusDevice;II)Ljava/nio/ByteBuffer;
|
||||||
|
public static final fun readHoldingRegistersToPacket (Lspace/kscience/controls/modbus/ModbusDevice;II)Lio/ktor/utils/io/core/ByteReadPacket;
|
||||||
|
public static final fun readInputDiscrete (Lspace/kscience/controls/modbus/ModbusDevice;I)Z
|
||||||
|
public static final fun readInputDiscretes (Lspace/kscience/controls/modbus/ModbusDevice;II)Lcom/ghgande/j2mod/modbus/util/BitVector;
|
||||||
|
public static final fun readInputRegister (Lspace/kscience/controls/modbus/ModbusDevice;I)S
|
||||||
|
public static final fun readInputRegisters (Lspace/kscience/controls/modbus/ModbusDevice;II)Ljava/util/List;
|
||||||
|
public static final fun readInputRegistersToBuffer (Lspace/kscience/controls/modbus/ModbusDevice;II)Ljava/nio/ByteBuffer;
|
||||||
|
public static final fun readInputRegistersToPacket (Lspace/kscience/controls/modbus/ModbusDevice;II)Lio/ktor/utils/io/core/ByteReadPacket;
|
||||||
|
public static final fun writeCoil (Lspace/kscience/controls/modbus/ModbusDevice;IZ)V
|
||||||
|
public static final fun writeCoil (Lspace/kscience/controls/modbus/ModbusDevice;Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;Z)V
|
||||||
|
public static final fun writeCoils (Lspace/kscience/controls/modbus/ModbusDevice;I[Z)V
|
||||||
|
public static final fun writeHoldingRegister (Lspace/kscience/controls/modbus/ModbusDevice;IS)I
|
||||||
|
public static final fun writeHoldingRegister (Lspace/kscience/controls/modbus/ModbusDevice;Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;S)I
|
||||||
|
public static final fun writeHoldingRegisters (Lspace/kscience/controls/modbus/ModbusDevice;ILjava/nio/ByteBuffer;)I
|
||||||
|
public static final fun writeHoldingRegisters (Lspace/kscience/controls/modbus/ModbusDevice;I[S)I
|
||||||
|
public static final fun writeShortRegister (Lspace/kscience/controls/modbus/ModbusDevice;IS)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/ModbusHub : java/lang/AutoCloseable, space/kscience/controls/api/DeviceHub {
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function0;Ljava/util/Map;)V
|
||||||
|
public fun close ()V
|
||||||
|
public final fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public fun getDevices ()Ljava/util/Map;
|
||||||
|
public final fun getMaster ()Lcom/ghgande/j2mod/modbus/facade/AbstractModbusMaster;
|
||||||
|
public final fun getMasterBuilder ()Lkotlin/jvm/functions/Function0;
|
||||||
|
public final fun getSpecs ()Ljava/util/Map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/controls/modbus/ModbusRegistryKey {
|
||||||
|
public abstract fun getAddress ()I
|
||||||
|
public fun getCount ()I
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/ModbusRegistryKey$Coil : space/kscience/controls/modbus/ModbusRegistryKey {
|
||||||
|
public fun <init> (I)V
|
||||||
|
public final fun component1 ()I
|
||||||
|
public final fun copy (I)Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;IILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getAddress ()I
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput : space/kscience/controls/modbus/ModbusRegistryKey {
|
||||||
|
public fun <init> (I)V
|
||||||
|
public final fun component1 ()I
|
||||||
|
public final fun copy (I)Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;IILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getAddress ()I
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/ModbusRegistryKey$HoldingRange : space/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister {
|
||||||
|
public fun <init> (IILspace/kscience/dataforge/io/IOFormat;)V
|
||||||
|
public fun getCount ()I
|
||||||
|
public final fun getEndAddress ()I
|
||||||
|
public final fun getFormat ()Lspace/kscience/dataforge/io/IOFormat;
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class space/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister : space/kscience/controls/modbus/ModbusRegistryKey {
|
||||||
|
public fun <init> (I)V
|
||||||
|
public fun getAddress ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/ModbusRegistryKey$InputRange : space/kscience/controls/modbus/ModbusRegistryKey$InputRegister {
|
||||||
|
public fun <init> (IILspace/kscience/dataforge/io/IOFormat;)V
|
||||||
|
public fun getCount ()I
|
||||||
|
public final fun getEndAddress ()I
|
||||||
|
public final fun getFormat ()Lspace/kscience/dataforge/io/IOFormat;
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class space/kscience/controls/modbus/ModbusRegistryKey$InputRegister : space/kscience/controls/modbus/ModbusRegistryKey {
|
||||||
|
public fun <init> (I)V
|
||||||
|
public fun getAddress ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/controls/modbus/ModbusRegistryMap {
|
||||||
|
public static final field Companion Lspace/kscience/controls/modbus/ModbusRegistryMap$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
protected final fun coil (ILjava/lang/String;)Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;
|
||||||
|
public static synthetic fun coil$default (Lspace/kscience/controls/modbus/ModbusRegistryMap;ILjava/lang/String;ILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$Coil;
|
||||||
|
protected final fun discrete (ILjava/lang/String;)Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;
|
||||||
|
public static synthetic fun discrete$default (Lspace/kscience/controls/modbus/ModbusRegistryMap;ILjava/lang/String;ILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$DiscreteInput;
|
||||||
|
public final fun getEntries ()Ljava/util/Map;
|
||||||
|
protected final fun input (IILspace/kscience/dataforge/io/IOFormat;Ljava/lang/String;)Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRange;
|
||||||
|
protected final fun input (ILjava/lang/String;)Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRegister;
|
||||||
|
public static synthetic fun input$default (Lspace/kscience/controls/modbus/ModbusRegistryMap;IILspace/kscience/dataforge/io/IOFormat;Ljava/lang/String;ILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRange;
|
||||||
|
public static synthetic fun input$default (Lspace/kscience/controls/modbus/ModbusRegistryMap;ILjava/lang/String;ILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$InputRegister;
|
||||||
|
protected final fun register (IILspace/kscience/dataforge/io/IOFormat;Ljava/lang/String;)Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRange;
|
||||||
|
protected final fun register (ILjava/lang/String;)Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;
|
||||||
|
protected final fun register (Lspace/kscience/controls/modbus/ModbusRegistryKey;Ljava/lang/String;)Lspace/kscience/controls/modbus/ModbusRegistryKey;
|
||||||
|
public static synthetic fun register$default (Lspace/kscience/controls/modbus/ModbusRegistryMap;IILspace/kscience/dataforge/io/IOFormat;Ljava/lang/String;ILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRange;
|
||||||
|
public static synthetic fun register$default (Lspace/kscience/controls/modbus/ModbusRegistryMap;ILjava/lang/String;ILjava/lang/Object;)Lspace/kscience/controls/modbus/ModbusRegistryKey$HoldingRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/modbus/ModbusRegistryMap$Companion {
|
||||||
|
public final fun print (Lspace/kscience/controls/modbus/ModbusRegistryMap;Ljava/lang/Appendable;)V
|
||||||
|
public static synthetic fun print$default (Lspace/kscience/controls/modbus/ModbusRegistryMap$Companion;Lspace/kscience/controls/modbus/ModbusRegistryMap;Ljava/lang/Appendable;ILjava/lang/Object;)V
|
||||||
|
public final fun validate (Lspace/kscience/controls/modbus/ModbusRegistryMap;)V
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,8 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.jvm")
|
id("space.kscience.gradle.jvm")
|
||||||
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
description = """
|
description = """
|
||||||
@ -11,3 +14,26 @@ dependencies {
|
|||||||
api(projects.controlsCore)
|
api(projects.controlsCore)
|
||||||
api("com.ghgande:j2mod:3.1.1")
|
api("com.ghgande:j2mod:3.1.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readme{
|
||||||
|
maturity = Maturity.EXPERIMENTAL
|
||||||
|
|
||||||
|
feature("modbusRegistryMap", ref = "src/main/kotlin/space/kscience/controls/modbus/ModbusRegistryMap.kt"){
|
||||||
|
"""
|
||||||
|
Type-safe modbus registry map. Allows to define both single-register and multi-register entries (using DataForge IO).
|
||||||
|
Automatically checks consistency.
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
feature("modbusProcessImage", ref = "src/main/kotlin/space/kscience/controls/modbus/DeviceProcessImage.kt"){
|
||||||
|
"""
|
||||||
|
Binding of slave (server) modbus device to Controls-kt device
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
feature("modbusDevice", ref = "src/main/kotlin/space/kscience/controls/modbus/ModbusDevice.kt"){
|
||||||
|
"""
|
||||||
|
A device with additional methods to work with modbus registers.
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,219 @@
|
|||||||
|
package space.kscience.controls.modbus
|
||||||
|
|
||||||
|
import com.ghgande.j2mod.modbus.procimg.*
|
||||||
|
import io.ktor.utils.io.core.buildPacket
|
||||||
|
import io.ktor.utils.io.core.readByteBuffer
|
||||||
|
import io.ktor.utils.io.core.writeShort
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import space.kscience.controls.api.Device
|
||||||
|
import space.kscience.controls.spec.DevicePropertySpec
|
||||||
|
import space.kscience.controls.spec.WritableDevicePropertySpec
|
||||||
|
import space.kscience.controls.spec.set
|
||||||
|
import space.kscience.controls.spec.useProperty
|
||||||
|
|
||||||
|
|
||||||
|
public class DeviceProcessImageBuilder<D : Device> internal constructor(
|
||||||
|
private val device: D,
|
||||||
|
public val image: ProcessImageImplementation,
|
||||||
|
) {
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.Coil,
|
||||||
|
block: D.(ObservableDigitalOut) -> Unit = {},
|
||||||
|
): ObservableDigitalOut {
|
||||||
|
val coil = ObservableDigitalOut()
|
||||||
|
device.block(coil)
|
||||||
|
image.addDigitalOut(key.address, coil)
|
||||||
|
return coil
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.Coil,
|
||||||
|
propertySpec: WritableDevicePropertySpec<D, Boolean>,
|
||||||
|
): ObservableDigitalOut = bind(key) { coil ->
|
||||||
|
coil.addObserver { _, _ ->
|
||||||
|
device[propertySpec] = coil.isSet
|
||||||
|
}
|
||||||
|
device.useProperty(propertySpec) { value ->
|
||||||
|
coil.set(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.DiscreteInput,
|
||||||
|
block: D.(SimpleDigitalIn) -> Unit = {},
|
||||||
|
): DigitalIn {
|
||||||
|
val input = SimpleDigitalIn()
|
||||||
|
device.block(input)
|
||||||
|
image.addDigitalIn(key.address, input)
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.DiscreteInput,
|
||||||
|
propertySpec: DevicePropertySpec<D, Boolean>,
|
||||||
|
): DigitalIn = bind(key) { input ->
|
||||||
|
device.useProperty(propertySpec) { value ->
|
||||||
|
input.set(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.InputRegister,
|
||||||
|
block: D.(SimpleInputRegister) -> Unit = {},
|
||||||
|
): SimpleInputRegister {
|
||||||
|
val input = SimpleInputRegister()
|
||||||
|
device.block(input)
|
||||||
|
image.addInputRegister(key.address, input)
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.InputRegister,
|
||||||
|
propertySpec: DevicePropertySpec<D, Short>,
|
||||||
|
): SimpleInputRegister = bind(key) { input ->
|
||||||
|
device.useProperty(propertySpec) { value ->
|
||||||
|
input.setValue(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.HoldingRegister,
|
||||||
|
block: D.(ObservableRegister) -> Unit = {},
|
||||||
|
): ObservableRegister {
|
||||||
|
val register = ObservableRegister()
|
||||||
|
device.block(register)
|
||||||
|
image.addRegister(key.address, register)
|
||||||
|
return register
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bind(
|
||||||
|
key: ModbusRegistryKey.HoldingRegister,
|
||||||
|
propertySpec: WritableDevicePropertySpec<D, Short>,
|
||||||
|
): ObservableRegister = bind(key) { register ->
|
||||||
|
register.addObserver { _, _ ->
|
||||||
|
device[propertySpec] = register.toShort()
|
||||||
|
}
|
||||||
|
device.useProperty(propertySpec) { value ->
|
||||||
|
register.setValue(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun <T> bind(key: ModbusRegistryKey.InputRange<T>, propertySpec: DevicePropertySpec<D, T>) {
|
||||||
|
val registers = List(key.count) {
|
||||||
|
SimpleInputRegister()
|
||||||
|
}
|
||||||
|
|
||||||
|
registers.forEachIndexed { index, register ->
|
||||||
|
image.addInputRegister(key.address + index, register)
|
||||||
|
}
|
||||||
|
|
||||||
|
device.useProperty(propertySpec) { value ->
|
||||||
|
val packet = buildPacket {
|
||||||
|
key.format.writeObject(this, value)
|
||||||
|
}.readByteBuffer()
|
||||||
|
registers.forEachIndexed { index, register ->
|
||||||
|
register.setValue(packet.getShort(index * 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun <T> bind(key: ModbusRegistryKey.HoldingRange<T>, propertySpec: WritableDevicePropertySpec<D, T>) {
|
||||||
|
val registers = List(key.count) {
|
||||||
|
ObservableRegister()
|
||||||
|
}
|
||||||
|
registers.forEachIndexed { index, register ->
|
||||||
|
register.addObserver { _, _ ->
|
||||||
|
val packet = buildPacket {
|
||||||
|
registers.forEach { value ->
|
||||||
|
writeShort(value.toShort())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
device[propertySpec] = key.format.readObject(packet)
|
||||||
|
}
|
||||||
|
image.addRegister(key.address + index, register)
|
||||||
|
}
|
||||||
|
|
||||||
|
device.useProperty(propertySpec) { value ->
|
||||||
|
val packet = buildPacket {
|
||||||
|
key.format.writeObject(this, value)
|
||||||
|
}.readByteBuffer()
|
||||||
|
registers.forEachIndexed { index, observableRegister ->
|
||||||
|
observableRegister.setValue(packet.getShort(index * 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bindAction(
|
||||||
|
key: ModbusRegistryKey.Coil,
|
||||||
|
action: suspend D.(Boolean) -> Unit,
|
||||||
|
): ObservableDigitalOut {
|
||||||
|
val coil = ObservableDigitalOut()
|
||||||
|
coil.addObserver { _, _ ->
|
||||||
|
device.launch {
|
||||||
|
device.action(coil.isSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image.addDigitalOut(key.address, coil)
|
||||||
|
return coil
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun bindAction(
|
||||||
|
key: ModbusRegistryKey.HoldingRegister,
|
||||||
|
action: suspend D.(Short) -> Unit,
|
||||||
|
): ObservableRegister {
|
||||||
|
val register = ObservableRegister()
|
||||||
|
register.addObserver { _, _ ->
|
||||||
|
|
||||||
|
with(device) {
|
||||||
|
launch {
|
||||||
|
action(register.toShort())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image.addRegister(key.address, register)
|
||||||
|
return register
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun <T> bindAction(
|
||||||
|
key: ModbusRegistryKey.HoldingRange<T>,
|
||||||
|
action: suspend D.(T) -> Unit,
|
||||||
|
): List<ObservableRegister> {
|
||||||
|
val registers = List(key.count) {
|
||||||
|
ObservableRegister()
|
||||||
|
}
|
||||||
|
registers.forEachIndexed { index, register ->
|
||||||
|
register.addObserver { _, _ ->
|
||||||
|
val packet = buildPacket {
|
||||||
|
registers.forEach { value ->
|
||||||
|
writeShort(value.toShort())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
device.launch {
|
||||||
|
device.action(key.format.readObject(packet))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image.addRegister(key.address + index, register)
|
||||||
|
}
|
||||||
|
|
||||||
|
return registers
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind the device to Modbus slave (server) image.
|
||||||
|
*/
|
||||||
|
public fun <D : Device> D.bindProcessImage(
|
||||||
|
openOnBind: Boolean = true,
|
||||||
|
binding: DeviceProcessImageBuilder<D>.() -> Unit,
|
||||||
|
): ProcessImage {
|
||||||
|
val image = SimpleProcessImage()
|
||||||
|
DeviceProcessImageBuilder(this, image).apply(binding)
|
||||||
|
if (openOnBind) {
|
||||||
|
launch {
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image
|
||||||
|
}
|
@ -3,8 +3,12 @@ package space.kscience.controls.modbus
|
|||||||
import com.ghgande.j2mod.modbus.facade.AbstractModbusMaster
|
import com.ghgande.j2mod.modbus.facade.AbstractModbusMaster
|
||||||
import com.ghgande.j2mod.modbus.procimg.InputRegister
|
import com.ghgande.j2mod.modbus.procimg.InputRegister
|
||||||
import com.ghgande.j2mod.modbus.procimg.Register
|
import com.ghgande.j2mod.modbus.procimg.Register
|
||||||
import com.ghgande.j2mod.modbus.procimg.SimpleRegister
|
import com.ghgande.j2mod.modbus.procimg.SimpleInputRegister
|
||||||
import com.ghgande.j2mod.modbus.util.BitVector
|
import com.ghgande.j2mod.modbus.util.BitVector
|
||||||
|
import io.ktor.utils.io.core.ByteReadPacket
|
||||||
|
import io.ktor.utils.io.core.buildPacket
|
||||||
|
import io.ktor.utils.io.core.readByteBuffer
|
||||||
|
import io.ktor.utils.io.core.writeShort
|
||||||
import space.kscience.controls.api.Device
|
import space.kscience.controls.api.Device
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
@ -22,37 +26,91 @@ public interface ModbusDevice : Device {
|
|||||||
public val clientId: Int
|
public val clientId: Int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The OPC-UA client initialized on first use
|
* The modubus master connector
|
||||||
*/
|
*/
|
||||||
public val master: AbstractModbusMaster
|
public val master: AbstractModbusMaster
|
||||||
|
|
||||||
|
public operator fun ModbusRegistryKey.Coil.getValue(thisRef: Any?, property: KProperty<*>): Boolean =
|
||||||
|
readCoil(address)
|
||||||
|
|
||||||
|
public operator fun ModbusRegistryKey.Coil.setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
|
||||||
|
writeCoil(address, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public operator fun ModbusRegistryKey.DiscreteInput.getValue(thisRef: Any?, property: KProperty<*>): Boolean =
|
||||||
|
readInputDiscrete(address)
|
||||||
|
|
||||||
|
public operator fun ModbusRegistryKey.InputRegister.getValue(thisRef: Any?, property: KProperty<*>): Short =
|
||||||
|
readInputRegister(address)
|
||||||
|
|
||||||
|
public operator fun <T> ModbusRegistryKey.InputRange<T>.getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
val packet = readInputRegistersToPacket(address, count)
|
||||||
|
return format.readObject(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public operator fun ModbusRegistryKey.HoldingRegister.getValue(thisRef: Any?, property: KProperty<*>): Short =
|
||||||
|
readHoldingRegister(address)
|
||||||
|
|
||||||
|
public operator fun ModbusRegistryKey.HoldingRegister.setValue(
|
||||||
|
thisRef: Any?,
|
||||||
|
property: KProperty<*>,
|
||||||
|
value: Short,
|
||||||
|
) {
|
||||||
|
writeHoldingRegister(address, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
public operator fun <T> ModbusRegistryKey.HoldingRange<T>.getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
val packet = readInputRegistersToPacket(address, count)
|
||||||
|
return format.readObject(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
public operator fun <T> ModbusRegistryKey.HoldingRange<T>.setValue(
|
||||||
|
thisRef: Any?,
|
||||||
|
property: KProperty<*>,
|
||||||
|
value: T,
|
||||||
|
) {
|
||||||
|
val buffer = buildPacket {
|
||||||
|
format.writeObject(this, value)
|
||||||
|
}.readByteBuffer()
|
||||||
|
writeHoldingRegisters(address, buffer)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read multiple sequential modbus coils (bit-values)
|
* Read multiple sequential modbus coils (bit-values)
|
||||||
*/
|
*/
|
||||||
public fun ModbusDevice.readCoils(ref: Int, count: Int): BitVector =
|
public fun ModbusDevice.readCoils(address: Int, count: Int): BitVector =
|
||||||
master.readCoils(clientId, ref, count)
|
master.readCoils(clientId, address, count)
|
||||||
|
|
||||||
public fun ModbusDevice.readCoil(ref: Int): Boolean =
|
public fun ModbusDevice.readCoil(address: Int): Boolean =
|
||||||
master.readCoils(clientId, ref, 1).getBit(0)
|
master.readCoils(clientId, address, 1).getBit(0)
|
||||||
|
|
||||||
public fun ModbusDevice.writeCoils(ref: Int, values: BooleanArray) {
|
public fun ModbusDevice.writeCoils(address: Int, values: BooleanArray) {
|
||||||
val bitVector = BitVector(values.size)
|
val bitVector = BitVector(values.size)
|
||||||
values.forEachIndexed { index, value ->
|
values.forEachIndexed { index, value ->
|
||||||
bitVector.setBit(index, value)
|
bitVector.setBit(index, value)
|
||||||
}
|
}
|
||||||
master.writeMultipleCoils(clientId, ref, bitVector)
|
master.writeMultipleCoils(clientId, address, bitVector)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun ModbusDevice.writeCoil(ref: Int, value: Boolean) {
|
public fun ModbusDevice.writeCoil(address: Int, value: Boolean) {
|
||||||
master.writeCoil(clientId, ref, value)
|
master.writeCoil(clientId, address, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun ModbusDevice.readInputDiscretes(ref: Int, count: Int): BitVector =
|
public fun ModbusDevice.writeCoil(key: ModbusRegistryKey.Coil, value: Boolean) {
|
||||||
master.readInputDiscretes(clientId, ref, count)
|
master.writeCoil(clientId, key.address, value)
|
||||||
|
}
|
||||||
|
|
||||||
public fun ModbusDevice.readInputRegisters(ref: Int, count: Int): List<InputRegister> =
|
public fun ModbusDevice.readInputDiscretes(address: Int, count: Int): BitVector =
|
||||||
master.readInputRegisters(clientId, ref, count).toList()
|
master.readInputDiscretes(clientId, address, count)
|
||||||
|
|
||||||
|
public fun ModbusDevice.readInputDiscrete(address: Int): Boolean =
|
||||||
|
master.readInputDiscretes(clientId, address, 1).getBit(0)
|
||||||
|
|
||||||
|
public fun ModbusDevice.readInputRegisters(address: Int, count: Int): List<InputRegister> =
|
||||||
|
master.readInputRegisters(clientId, address, count).toList()
|
||||||
|
|
||||||
private fun Array<out InputRegister>.toBuffer(): ByteBuffer {
|
private fun Array<out InputRegister>.toBuffer(): ByteBuffer {
|
||||||
val buffer: ByteBuffer = ByteBuffer.allocate(size * 2)
|
val buffer: ByteBuffer = ByteBuffer.allocate(size * 2)
|
||||||
@ -64,83 +122,88 @@ private fun Array<out InputRegister>.toBuffer(): ByteBuffer {
|
|||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun ModbusDevice.readInputRegistersToBuffer(ref: Int, count: Int): ByteBuffer =
|
private fun Array<out InputRegister>.toPacket(): ByteReadPacket = buildPacket {
|
||||||
master.readInputRegisters(clientId, ref, count).toBuffer()
|
forEach { value ->
|
||||||
|
writeShort(value.toShort())
|
||||||
public fun ModbusDevice.readDoubleInput(ref: Int): Double =
|
|
||||||
readInputRegistersToBuffer(ref, Double.SIZE_BYTES).getDouble()
|
|
||||||
|
|
||||||
public fun ModbusDevice.readShortInput(ref: Int): Short =
|
|
||||||
readInputRegisters(ref, 1).first().toShort()
|
|
||||||
|
|
||||||
public fun ModbusDevice.readHoldingRegisters(ref: Int, count: Int): List<Register> =
|
|
||||||
master.readMultipleRegisters(clientId, ref, count).toList()
|
|
||||||
|
|
||||||
public fun ModbusDevice.readHoldingRegistersToBuffer(ref: Int, count: Int): ByteBuffer =
|
|
||||||
master.readMultipleRegisters(clientId, ref, count).toBuffer()
|
|
||||||
|
|
||||||
public fun ModbusDevice.readDoubleRegister(ref: Int): Double =
|
|
||||||
readHoldingRegistersToBuffer(ref, Double.SIZE_BYTES).getDouble()
|
|
||||||
|
|
||||||
public fun ModbusDevice.readShortRegister(ref: Int): Short =
|
|
||||||
readHoldingRegisters(ref, 1).first().toShort()
|
|
||||||
|
|
||||||
public fun ModbusDevice.writeHoldingRegisters(ref: Int, values: ShortArray): Int =
|
|
||||||
master.writeMultipleRegisters(
|
|
||||||
clientId,
|
|
||||||
ref,
|
|
||||||
Array<Register>(values.size) { SimpleRegister().apply { setValue(values[it]) } }
|
|
||||||
)
|
|
||||||
|
|
||||||
public fun ModbusDevice.writeHoldingRegister(ref: Int, value: Short): Int =
|
|
||||||
master.writeSingleRegister(
|
|
||||||
clientId,
|
|
||||||
ref,
|
|
||||||
SimpleRegister().apply { setValue(value) }
|
|
||||||
)
|
|
||||||
|
|
||||||
public fun ModbusDevice.writeHoldingRegisters(ref: Int, buffer: ByteBuffer): Int {
|
|
||||||
val array = ShortArray(buffer.limit().floorDiv(2)) { buffer.getShort(it * 2) }
|
|
||||||
|
|
||||||
return writeHoldingRegisters(ref, array)
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun ModbusDevice.writeShortRegister(ref: Int, value: Short) {
|
|
||||||
master.writeSingleRegister(ref, SimpleRegister().apply { setValue(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun ModbusDevice.modBusRegister(
|
|
||||||
ref: Int,
|
|
||||||
): ReadWriteProperty<ModbusDevice, Short> = object : ReadWriteProperty<ModbusDevice, Short> {
|
|
||||||
override fun getValue(thisRef: ModbusDevice, property: KProperty<*>): Short = readShortRegister(ref)
|
|
||||||
|
|
||||||
override fun setValue(thisRef: ModbusDevice, property: KProperty<*>, value: Short) {
|
|
||||||
writeHoldingRegister(ref, value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun ModbusDevice.modBusDoubleRegister(
|
public fun ModbusDevice.readInputRegistersToBuffer(address: Int, count: Int): ByteBuffer =
|
||||||
ref: Int,
|
master.readInputRegisters(clientId, address, count).toBuffer()
|
||||||
|
|
||||||
|
public fun ModbusDevice.readInputRegistersToPacket(address: Int, count: Int): ByteReadPacket =
|
||||||
|
master.readInputRegisters(clientId, address, count).toPacket()
|
||||||
|
|
||||||
|
public fun ModbusDevice.readDoubleInput(address: Int): Double =
|
||||||
|
readInputRegistersToBuffer(address, Double.SIZE_BYTES).getDouble()
|
||||||
|
|
||||||
|
public fun ModbusDevice.readInputRegister(address: Int): Short =
|
||||||
|
readInputRegisters(address, 1).first().toShort()
|
||||||
|
|
||||||
|
public fun ModbusDevice.readHoldingRegisters(address: Int, count: Int): List<Register> =
|
||||||
|
master.readMultipleRegisters(clientId, address, count).toList()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a number of registers to a [ByteBuffer]
|
||||||
|
* @param address of a register
|
||||||
|
* @param count number of 2-bytes registers to read. Buffer size is 2*[count]
|
||||||
|
*/
|
||||||
|
public fun ModbusDevice.readHoldingRegistersToBuffer(address: Int, count: Int): ByteBuffer =
|
||||||
|
master.readMultipleRegisters(clientId, address, count).toBuffer()
|
||||||
|
|
||||||
|
public fun ModbusDevice.readHoldingRegistersToPacket(address: Int, count: Int): ByteReadPacket =
|
||||||
|
master.readMultipleRegisters(clientId, address, count).toPacket()
|
||||||
|
|
||||||
|
public fun ModbusDevice.readDoubleRegister(address: Int): Double =
|
||||||
|
readHoldingRegistersToBuffer(address, Double.SIZE_BYTES).getDouble()
|
||||||
|
|
||||||
|
public fun ModbusDevice.readHoldingRegister(address: Int): Short =
|
||||||
|
readHoldingRegisters(address, 1).first().toShort()
|
||||||
|
|
||||||
|
public fun ModbusDevice.writeHoldingRegisters(address: Int, values: ShortArray): Int =
|
||||||
|
master.writeMultipleRegisters(
|
||||||
|
clientId,
|
||||||
|
address,
|
||||||
|
Array<Register>(values.size) { SimpleInputRegister(values[it].toInt()) }
|
||||||
|
)
|
||||||
|
|
||||||
|
public fun ModbusDevice.writeHoldingRegister(address: Int, value: Short): Int =
|
||||||
|
master.writeSingleRegister(
|
||||||
|
clientId,
|
||||||
|
address,
|
||||||
|
SimpleInputRegister(value.toInt())
|
||||||
|
)
|
||||||
|
|
||||||
|
public fun ModbusDevice.writeHoldingRegister(key: ModbusRegistryKey.HoldingRegister, value: Short): Int =
|
||||||
|
writeHoldingRegister(key.address, value)
|
||||||
|
|
||||||
|
public fun ModbusDevice.writeHoldingRegisters(address: Int, buffer: ByteBuffer): Int {
|
||||||
|
val array: ShortArray = ShortArray(buffer.limit().floorDiv(2)) { buffer.getShort(it * 2) }
|
||||||
|
|
||||||
|
return writeHoldingRegisters(address, array)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun ModbusDevice.writeShortRegister(address: Int, value: Short) {
|
||||||
|
master.writeSingleRegister(address, SimpleInputRegister(value.toInt()))
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun ModbusDevice.modbusRegister(
|
||||||
|
address: Int,
|
||||||
|
): ReadWriteProperty<ModbusDevice, Short> = object : ReadWriteProperty<ModbusDevice, Short> {
|
||||||
|
override fun getValue(thisRef: ModbusDevice, property: KProperty<*>): Short = readHoldingRegister(address)
|
||||||
|
|
||||||
|
override fun setValue(thisRef: ModbusDevice, property: KProperty<*>, value: Short) {
|
||||||
|
writeHoldingRegister(address, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun ModbusDevice.modbusDoubleRegister(
|
||||||
|
address: Int,
|
||||||
): ReadWriteProperty<ModbusDevice, Double> = object : ReadWriteProperty<ModbusDevice, Double> {
|
): ReadWriteProperty<ModbusDevice, Double> = object : ReadWriteProperty<ModbusDevice, Double> {
|
||||||
override fun getValue(thisRef: ModbusDevice, property: KProperty<*>): Double = readDoubleRegister(ref)
|
override fun getValue(thisRef: ModbusDevice, property: KProperty<*>): Double = readDoubleRegister(address)
|
||||||
|
|
||||||
override fun setValue(thisRef: ModbusDevice, property: KProperty<*>, value: Double) {
|
override fun setValue(thisRef: ModbusDevice, property: KProperty<*>, value: Double) {
|
||||||
val buffer = ByteBuffer.allocate(Double.SIZE_BYTES).apply { putDouble(value) }
|
val buffer = ByteBuffer.allocate(Double.SIZE_BYTES).apply { putDouble(value) }
|
||||||
writeHoldingRegisters(ref, buffer)
|
writeHoldingRegisters(address, buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
//public inline fun <reified T> ModbusDevice.opcDouble(
|
|
||||||
//): ReadWriteProperty<Any?, Double> = ma
|
|
||||||
//
|
|
||||||
//public inline fun <reified T> ModbusDeviceBySpec<*>.opcInt(
|
|
||||||
// nodeId: NodeId,
|
|
||||||
// magAge: Double = 1.0,
|
|
||||||
//): ReadWriteProperty<Any?, Int> = opc(nodeId, MetaConverter.int, magAge)
|
|
||||||
//
|
|
||||||
//public inline fun <reified T> ModbusDeviceBySpec<*>.opcString(
|
|
||||||
// nodeId: NodeId,
|
|
||||||
// magAge: Double = 1.0,
|
|
||||||
//): ReadWriteProperty<Any?, String> = opc(nodeId, MetaConverter.string, magAge)
|
|
||||||
|
@ -17,8 +17,21 @@ public open class ModbusDeviceBySpec<D: Device>(
|
|||||||
spec: DeviceSpec<D>,
|
spec: DeviceSpec<D>,
|
||||||
override val clientId: Int,
|
override val clientId: Int,
|
||||||
override val master: AbstractModbusMaster,
|
override val master: AbstractModbusMaster,
|
||||||
|
private val disposeMasterOnClose: Boolean = true,
|
||||||
meta: Meta = Meta.EMPTY,
|
meta: Meta = Meta.EMPTY,
|
||||||
) : ModbusDevice, DeviceBySpec<D>(spec, context, meta)
|
) : ModbusDevice, DeviceBySpec<D>(spec, context, meta){
|
||||||
|
override suspend fun open() {
|
||||||
|
master.connect()
|
||||||
|
super<DeviceBySpec>.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
if(disposeMasterOnClose){
|
||||||
|
master.disconnect()
|
||||||
|
}
|
||||||
|
super<ModbusDevice>.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class ModbusHub(
|
public class ModbusHub(
|
||||||
|
@ -1,44 +1,163 @@
|
|||||||
package space.kscience.controls.modbus
|
package space.kscience.controls.modbus
|
||||||
|
|
||||||
|
import space.kscience.dataforge.io.IOFormat
|
||||||
|
|
||||||
|
|
||||||
public sealed class ModbusRegistryKey {
|
public sealed class ModbusRegistryKey {
|
||||||
|
public abstract val address: Int
|
||||||
|
public open val count: Int = 1
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read-only boolean value
|
* Read-only boolean value
|
||||||
*/
|
*/
|
||||||
public class Coil(public val address: Int) : ModbusRegistryKey() {
|
public data class Coil(override val address: Int) : ModbusRegistryKey()
|
||||||
init {
|
|
||||||
require(address in 1..9999) { "Coil address must be in 1..9999 range" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read-write boolean value
|
* Read-write boolean value
|
||||||
*/
|
*/
|
||||||
public class DiscreteInput(public val address: Int) : ModbusRegistryKey() {
|
public data class DiscreteInput(override val address: Int) : ModbusRegistryKey()
|
||||||
init {
|
|
||||||
require(address in 10001..19999) { "DiscreteInput address must be in 10001..19999 range" }
|
/**
|
||||||
}
|
* Read-only binary value
|
||||||
|
*/
|
||||||
|
public open class InputRegister(override val address: Int) : ModbusRegistryKey() {
|
||||||
|
override fun toString(): String = "InputRegister(address=$address)"
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InputRegister(public val address: Int) : ModbusRegistryKey() {
|
public class InputRange<T>(
|
||||||
init {
|
address: Int,
|
||||||
require(address in 20001..29999) { "InputRegister address must be in 20001..29999 range" }
|
override val count: Int,
|
||||||
}
|
public val format: IOFormat<T>,
|
||||||
|
) : InputRegister(address) {
|
||||||
|
public val endAddress: Int get() = address + count
|
||||||
|
override fun toString(): String = "InputRange(count=$count, format=$format)"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HoldingRegister(public val address: Int) : ModbusRegistryKey() {
|
public open class HoldingRegister(override val address: Int) : ModbusRegistryKey() {
|
||||||
init {
|
override fun toString(): String = "HoldingRegister(address=$address)"
|
||||||
require(address in 30001..39999) { "HoldingRegister address must be in 30001..39999 range" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class HoldingRange<T>(
|
||||||
|
address: Int,
|
||||||
|
override val count: Int,
|
||||||
|
public val format: IOFormat<T>,
|
||||||
|
) : HoldingRegister(address) {
|
||||||
|
public val endAddress: Int get() = address + count
|
||||||
|
override fun toString(): String = "HoldingRange(count=$count, format=$format)"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ModbusRegistryMap {
|
public abstract class ModbusRegistryMap {
|
||||||
protected fun coil(address: Int): ModbusRegistryKey.Coil = ModbusRegistryKey.Coil(address)
|
|
||||||
|
|
||||||
protected fun discrete(address: Int): ModbusRegistryKey.DiscreteInput = ModbusRegistryKey.DiscreteInput(address)
|
private val _entries: MutableMap<ModbusRegistryKey, String> = mutableMapOf<ModbusRegistryKey, String>()
|
||||||
|
|
||||||
protected fun input(address: Int): ModbusRegistryKey.InputRegister = ModbusRegistryKey.InputRegister(address)
|
public val entries: Map<ModbusRegistryKey, String> get() = _entries
|
||||||
|
|
||||||
protected fun register(address: Int): ModbusRegistryKey.HoldingRegister = ModbusRegistryKey.HoldingRegister(address)
|
protected fun <T : ModbusRegistryKey> register(key: T, description: String): T {
|
||||||
|
_entries[key] = description
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun coil(address: Int, description: String = ""): ModbusRegistryKey.Coil =
|
||||||
|
register(ModbusRegistryKey.Coil(address), description)
|
||||||
|
|
||||||
|
|
||||||
|
protected fun discrete(address: Int, description: String = ""): ModbusRegistryKey.DiscreteInput =
|
||||||
|
register(ModbusRegistryKey.DiscreteInput(address), description)
|
||||||
|
|
||||||
|
protected fun input(address: Int, description: String = ""): ModbusRegistryKey.InputRegister =
|
||||||
|
register(ModbusRegistryKey.InputRegister(address), description)
|
||||||
|
|
||||||
|
protected fun <T> input(
|
||||||
|
address: Int,
|
||||||
|
count: Int,
|
||||||
|
reader: IOFormat<T>,
|
||||||
|
description: String = "",
|
||||||
|
): ModbusRegistryKey.InputRange<T> =
|
||||||
|
register(ModbusRegistryKey.InputRange(address, count, reader), description)
|
||||||
|
|
||||||
|
protected fun register(address: Int, description: String = ""): ModbusRegistryKey.HoldingRegister =
|
||||||
|
register(ModbusRegistryKey.HoldingRegister(address), description)
|
||||||
|
|
||||||
|
protected fun <T> register(
|
||||||
|
address: Int,
|
||||||
|
count: Int,
|
||||||
|
format: IOFormat<T>,
|
||||||
|
description: String = "",
|
||||||
|
): ModbusRegistryKey.HoldingRange<T> =
|
||||||
|
register(ModbusRegistryKey.HoldingRange(address, count, format), description)
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
public fun validate(map: ModbusRegistryMap) {
|
||||||
|
var lastCoil: ModbusRegistryKey.Coil? = null
|
||||||
|
var lastDiscreteInput: ModbusRegistryKey.DiscreteInput? = null
|
||||||
|
var lastInput: ModbusRegistryKey.InputRegister? = null
|
||||||
|
var lastRegister: ModbusRegistryKey.HoldingRegister? = null
|
||||||
|
map.entries.keys.sortedBy { it.address }.forEach { key ->
|
||||||
|
when (key) {
|
||||||
|
is ModbusRegistryKey.Coil -> if (lastCoil?.let { key.address >= it.address + it.count } != false) {
|
||||||
|
lastCoil = key
|
||||||
|
} else {
|
||||||
|
error("Key $lastCoil overlaps with key $key")
|
||||||
|
}
|
||||||
|
|
||||||
|
is ModbusRegistryKey.DiscreteInput -> if (lastDiscreteInput?.let { key.address >= it.address + it.count } != false) {
|
||||||
|
lastDiscreteInput = key
|
||||||
|
} else {
|
||||||
|
error("Key $lastDiscreteInput overlaps with key $key")
|
||||||
|
}
|
||||||
|
|
||||||
|
is ModbusRegistryKey.InputRegister -> if (lastInput?.let { key.address >= it.address + it.count } != false) {
|
||||||
|
lastInput = key
|
||||||
|
} else {
|
||||||
|
error("Key $lastInput overlaps with key $key")
|
||||||
|
}
|
||||||
|
|
||||||
|
is ModbusRegistryKey.HoldingRegister -> if (lastRegister?.let { key.address >= it.address + it.count } != false) {
|
||||||
|
lastRegister = key
|
||||||
|
} else {
|
||||||
|
error("Key $lastRegister overlaps with key $key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ModbusRegistryKey.sectionNumber
|
||||||
|
get() = when (this) {
|
||||||
|
is ModbusRegistryKey.Coil -> 1
|
||||||
|
is ModbusRegistryKey.DiscreteInput -> 2
|
||||||
|
is ModbusRegistryKey.HoldingRegister -> 4
|
||||||
|
is ModbusRegistryKey.InputRegister -> 3
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun print(map: ModbusRegistryMap, to: Appendable = System.out) {
|
||||||
|
validate(map)
|
||||||
|
map.entries.entries
|
||||||
|
.sortedWith(
|
||||||
|
Comparator.comparingInt<Map.Entry<ModbusRegistryKey, String>?> { it.key.sectionNumber }
|
||||||
|
.thenComparingInt { it.key.address }
|
||||||
|
)
|
||||||
|
.forEach { (key, description) ->
|
||||||
|
val typeString = when (key) {
|
||||||
|
is ModbusRegistryKey.Coil -> "Coil"
|
||||||
|
is ModbusRegistryKey.DiscreteInput -> "Discrete"
|
||||||
|
is ModbusRegistryKey.HoldingRegister -> "Register"
|
||||||
|
is ModbusRegistryKey.InputRegister -> "Input"
|
||||||
|
}
|
||||||
|
val rangeString = if (key.count == 1) {
|
||||||
|
key.address.toString()
|
||||||
|
} else {
|
||||||
|
"${key.address} - ${key.address + key.count}"
|
||||||
|
}
|
||||||
|
to.appendLine("${typeString}\t$rangeString\t$description")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,29 @@
|
|||||||
# Module controls-opcua
|
# Module controls-opcua
|
||||||
|
|
||||||
|
A client and server connectors for OPC-UA via Eclipse Milo
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [opcuaClient](src/main/kotlin/space/kscience/controls/opcua/client) : Connect a Controls-kt as a client to OPC UA server
|
||||||
|
- [opcuaServer](src/main/kotlin/space/kscience/controls/opcua/server) : Create an OPC UA server on top of Controls-kt device (or device hub)
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## Artifact:
|
||||||
|
|
||||||
|
The Maven coordinates of this project are `space.kscience:controls-opcua:0.2.0`.
|
||||||
|
|
||||||
|
**Gradle Kotlin DSL:**
|
||||||
|
```kotlin
|
||||||
|
repositories {
|
||||||
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("space.kscience:controls-opcua:0.2.0")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
82
controls-opcua/api/controls-opcua.api
Normal file
82
controls-opcua/api/controls-opcua.api
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
public final class space/kscience/controls/opcua/client/MetaBsdParser : org/eclipse/milo/opcua/binaryschema/parser/BsdParser {
|
||||||
|
public fun <init> ()V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/client/MetaBsdParserKt {
|
||||||
|
public static final fun toMeta (Lorg/eclipse/milo/opcua/stack/core/types/builtin/Variant;Lorg/eclipse/milo/opcua/stack/core/serialization/SerializationContext;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/client/MiloConfiguration : space/kscience/dataforge/meta/Scheme {
|
||||||
|
public static final field Companion Lspace/kscience/controls/opcua/client/MiloConfiguration$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun getEndpointUrl ()Ljava/lang/String;
|
||||||
|
public final fun getSecurityPolicy ()Lorg/eclipse/milo/opcua/stack/core/security/SecurityPolicy;
|
||||||
|
public final fun getUsername ()Lspace/kscience/controls/opcua/client/MiloUsername;
|
||||||
|
public final fun setEndpointUrl (Ljava/lang/String;)V
|
||||||
|
public final fun setSecurityPolicy (Lorg/eclipse/milo/opcua/stack/core/security/SecurityPolicy;)V
|
||||||
|
public final fun setUsername (Lspace/kscience/controls/opcua/client/MiloUsername;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/client/MiloConfiguration$Companion : space/kscience/dataforge/meta/SchemeSpec {
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/controls/opcua/client/MiloIdentity : space/kscience/dataforge/meta/Scheme {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/client/MiloUsername : space/kscience/controls/opcua/client/MiloIdentity {
|
||||||
|
public static final field Companion Lspace/kscience/controls/opcua/client/MiloUsername$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun getPassword ()Ljava/lang/String;
|
||||||
|
public final fun getUsername ()Ljava/lang/String;
|
||||||
|
public final fun setPassword (Ljava/lang/String;)V
|
||||||
|
public final fun setUsername (Ljava/lang/String;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/client/MiloUsername$Companion : space/kscience/dataforge/meta/SchemeSpec {
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/opcua/client/OpcUaDevice : space/kscience/controls/api/Device {
|
||||||
|
public abstract fun getClient ()Lorg/eclipse/milo/opcua/sdk/client/OpcUaClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class space/kscience/controls/opcua/client/OpcUaDeviceBySpec : space/kscience/controls/spec/DeviceBySpec, space/kscience/controls/opcua/client/OpcUaDevice {
|
||||||
|
public fun <init> (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/controls/opcua/client/MiloConfiguration;Lspace/kscience/dataforge/context/Context;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/controls/spec/DeviceSpec;Lspace/kscience/controls/opcua/client/MiloConfiguration;Lspace/kscience/dataforge/context/Context;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun getClient ()Lorg/eclipse/milo/opcua/sdk/client/OpcUaClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/client/OpcUaDeviceKt {
|
||||||
|
public static final fun opcDouble (Lspace/kscience/controls/opcua/client/OpcUaDevice;Lorg/eclipse/milo/opcua/stack/core/types/builtin/NodeId;D)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
public static synthetic fun opcDouble$default (Lspace/kscience/controls/opcua/client/OpcUaDevice;Lorg/eclipse/milo/opcua/stack/core/types/builtin/NodeId;DILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
public static final fun opcInt (Lspace/kscience/controls/opcua/client/OpcUaDevice;Lorg/eclipse/milo/opcua/stack/core/types/builtin/NodeId;D)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
public static synthetic fun opcInt$default (Lspace/kscience/controls/opcua/client/OpcUaDevice;Lorg/eclipse/milo/opcua/stack/core/types/builtin/NodeId;DILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
public static final fun opcString (Lspace/kscience/controls/opcua/client/OpcUaDevice;Lorg/eclipse/milo/opcua/stack/core/types/builtin/NodeId;D)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
public static synthetic fun opcString$default (Lspace/kscience/controls/opcua/client/OpcUaDevice;Lorg/eclipse/milo/opcua/stack/core/types/builtin/NodeId;DILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/server/DeviceNameSpace : org/eclipse/milo/opcua/sdk/server/api/ManagedNamespaceWithLifecycle {
|
||||||
|
public static final field Companion Lspace/kscience/controls/opcua/server/DeviceNameSpace$Companion;
|
||||||
|
public static final field NAMESPACE_URI Ljava/lang/String;
|
||||||
|
public fun <init> (Lorg/eclipse/milo/opcua/sdk/server/OpcUaServer;Lspace/kscience/controls/manager/DeviceManager;)V
|
||||||
|
public final fun getDeviceManager ()Lspace/kscience/controls/manager/DeviceManager;
|
||||||
|
public fun onDataItemsCreated (Ljava/util/List;)V
|
||||||
|
public fun onDataItemsDeleted (Ljava/util/List;)V
|
||||||
|
public fun onDataItemsModified (Ljava/util/List;)V
|
||||||
|
public fun onMonitoringModeChanged (Ljava/util/List;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/server/DeviceNameSpace$Companion {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/server/DeviceNameSpaceKt {
|
||||||
|
public static final fun get (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/api/PropertyDescriptor;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public static final fun read (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/api/PropertyDescriptor;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun serveDevices (Lorg/eclipse/milo/opcua/sdk/server/OpcUaServer;Lspace/kscience/controls/manager/DeviceManager;)Lspace/kscience/controls/opcua/server/DeviceNameSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/opcua/server/ServerUtilsKt {
|
||||||
|
public static final fun OpcUaServer (Lkotlin/jvm/functions/Function1;)Lorg/eclipse/milo/opcua/sdk/server/OpcUaServer;
|
||||||
|
public static final fun endpoint (Lorg/eclipse/milo/opcua/sdk/server/api/config/OpcUaServerConfigBuilder;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,17 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.jvm")
|
id("space.kscience.gradle.jvm")
|
||||||
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description = """
|
||||||
|
A client and server connectors for OPC-UA via Eclipse Milo
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
val ktorVersion: String by rootProject.extra
|
val ktorVersion: String by rootProject.extra
|
||||||
|
|
||||||
val miloVersion: String = "0.6.9"
|
val miloVersion: String = "0.6.10"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.controlsCore)
|
api(projects.controlsCore)
|
||||||
@ -16,3 +23,19 @@ dependencies {
|
|||||||
|
|
||||||
testImplementation(spclibs.kotlinx.coroutines.test)
|
testImplementation(spclibs.kotlinx.coroutines.test)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readme{
|
||||||
|
maturity = Maturity.EXPERIMENTAL
|
||||||
|
|
||||||
|
feature("opcuaClient", ref = "src/main/kotlin/space/kscience/controls/opcua/client"){
|
||||||
|
"""
|
||||||
|
Connect a Controls-kt as a client to OPC UA server
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
feature("opcuaServer", ref = "src/main/kotlin/space/kscience/controls/opcua/server"){
|
||||||
|
"""
|
||||||
|
Create an OPC UA server on top of Controls-kt device (or device hub)
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package space.kscience.controls.opcua.client
|
package space.kscience.controls.opcua.client
|
||||||
|
|
||||||
|
import kotlinx.datetime.toJavaInstant
|
||||||
|
import kotlinx.datetime.toKotlinInstant
|
||||||
import org.eclipse.milo.opcua.binaryschema.AbstractCodec
|
import org.eclipse.milo.opcua.binaryschema.AbstractCodec
|
||||||
import org.eclipse.milo.opcua.binaryschema.parser.BsdParser
|
import org.eclipse.milo.opcua.binaryschema.parser.BsdParser
|
||||||
import org.eclipse.milo.opcua.stack.core.UaSerializationException
|
import org.eclipse.milo.opcua.stack.core.UaSerializationException
|
||||||
@ -66,7 +68,7 @@ internal fun opcToMeta(value: Any?): Meta = when (value) {
|
|||||||
is Boolean -> Meta(value.asValue())
|
is Boolean -> Meta(value.asValue())
|
||||||
is String -> Meta(value.asValue())
|
is String -> Meta(value.asValue())
|
||||||
is Char -> Meta(value.toString().asValue())
|
is Char -> Meta(value.toString().asValue())
|
||||||
is DateTime -> value.javaInstant.toMeta()
|
is DateTime -> value.javaInstant.toKotlinInstant().toMeta()
|
||||||
is UUID -> Meta(value.toString().asValue())
|
is UUID -> Meta(value.toString().asValue())
|
||||||
is QualifiedName -> Meta {
|
is QualifiedName -> Meta {
|
||||||
"namespaceIndex" put value.namespaceIndex
|
"namespaceIndex" put value.namespaceIndex
|
||||||
@ -79,9 +81,9 @@ internal fun opcToMeta(value: Any?): Meta = when (value) {
|
|||||||
is DataValue -> Meta {
|
is DataValue -> Meta {
|
||||||
"value" put opcToMeta(value.value) // need SerializationContext to do that properly
|
"value" put opcToMeta(value.value) // need SerializationContext to do that properly
|
||||||
value.statusCode?.value?.let { "status" put Meta(it.asValue()) }
|
value.statusCode?.value?.let { "status" put Meta(it.asValue()) }
|
||||||
value.sourceTime?.javaInstant?.let { "sourceTime" put it.toMeta() }
|
value.sourceTime?.javaInstant?.let { "sourceTime" put it.toKotlinInstant().toMeta() }
|
||||||
value.sourcePicoseconds?.let { "sourcePicoseconds" put Meta(it.asValue()) }
|
value.sourcePicoseconds?.let { "sourcePicoseconds" put Meta(it.asValue()) }
|
||||||
value.serverTime?.javaInstant?.let { "serverTime" put it.toMeta() }
|
value.serverTime?.javaInstant?.let { "serverTime" put it.toKotlinInstant().toMeta() }
|
||||||
value.serverPicoseconds?.let { "serverPicoseconds" put Meta(it.asValue()) }
|
value.serverPicoseconds?.let { "serverPicoseconds" put Meta(it.asValue()) }
|
||||||
}
|
}
|
||||||
is ByteString -> Meta(value.bytesOrEmpty().asValue())
|
is ByteString -> Meta(value.bytesOrEmpty().asValue())
|
||||||
@ -145,7 +147,7 @@ internal class MetaStructureCodec(
|
|||||||
"Float" -> member.value?.numberOrNull?.toFloat()
|
"Float" -> member.value?.numberOrNull?.toFloat()
|
||||||
"Double" -> member.value?.numberOrNull?.toDouble()
|
"Double" -> member.value?.numberOrNull?.toDouble()
|
||||||
"String" -> member.string
|
"String" -> member.string
|
||||||
"DateTime" -> DateTime(member.instant())
|
"DateTime" -> DateTime(member.instant().toJavaInstant())
|
||||||
"Guid" -> member.string?.let { UUID.fromString(it) }
|
"Guid" -> member.string?.let { UUID.fromString(it) }
|
||||||
"ByteString" -> member.value?.list?.let { list ->
|
"ByteString" -> member.value?.list?.let { list ->
|
||||||
ByteString(list.map { it.number.toByte() }.toByteArray())
|
ByteString(list.map { it.number.toByte() }.toByteArray())
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package space.kscience.controls.opcua.client
|
package space.kscience.controls.opcua.client
|
||||||
|
|
||||||
import org.eclipse.milo.opcua.sdk.client.OpcUaClient
|
import org.eclipse.milo.opcua.sdk.client.OpcUaClient
|
||||||
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider
|
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder
|
||||||
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider
|
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider
|
||||||
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy
|
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy
|
||||||
import space.kscience.controls.api.Device
|
import space.kscience.controls.api.Device
|
||||||
@ -12,12 +12,12 @@ import space.kscience.dataforge.context.Global
|
|||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.*
|
||||||
|
|
||||||
|
|
||||||
public sealed class MiloIdentity: Scheme()
|
public sealed class MiloIdentity : Scheme()
|
||||||
|
|
||||||
public class MiloUsername : MiloIdentity() {
|
public class MiloUsername : MiloIdentity() {
|
||||||
|
|
||||||
public var username: String by string{ error("Username not defined") }
|
public var username: String by string { error("Username not defined") }
|
||||||
public var password: String by string{ error("Password not defined") }
|
public var password: String by string { error("Password not defined") }
|
||||||
|
|
||||||
public companion object : SchemeSpec<MiloUsername>(::MiloUsername)
|
public companion object : SchemeSpec<MiloUsername>(::MiloUsername)
|
||||||
}
|
}
|
||||||
@ -35,6 +35,12 @@ public class MiloConfiguration : Scheme() {
|
|||||||
|
|
||||||
public var securityPolicy: SecurityPolicy by enum(SecurityPolicy.None)
|
public var securityPolicy: SecurityPolicy by enum(SecurityPolicy.None)
|
||||||
|
|
||||||
|
internal fun configureClient(builder: OpcUaClientConfigBuilder) {
|
||||||
|
username?.let {
|
||||||
|
builder.setIdentityProvider(UsernameProvider(it.username, it.password))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public companion object : SchemeSpec<MiloConfiguration>(::MiloConfiguration)
|
public companion object : SchemeSpec<MiloConfiguration>(::MiloConfiguration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,9 +57,7 @@ public open class OpcUaDeviceBySpec<D : Device>(
|
|||||||
context.createOpcUaClient(
|
context.createOpcUaClient(
|
||||||
config.endpointUrl,
|
config.endpointUrl,
|
||||||
securityPolicy = config.securityPolicy,
|
securityPolicy = config.securityPolicy,
|
||||||
identityProvider = config.username?.let {
|
opcClientConfig = { config.configureClient(this) }
|
||||||
UsernameProvider(it.username,it.password)
|
|
||||||
} ?: AnonymousProvider()
|
|
||||||
).apply {
|
).apply {
|
||||||
connect().get()
|
connect().get()
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package space.kscience.controls.opcua.client
|
|||||||
import org.eclipse.milo.opcua.sdk.client.OpcUaClient
|
import org.eclipse.milo.opcua.sdk.client.OpcUaClient
|
||||||
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder
|
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder
|
||||||
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider
|
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider
|
||||||
import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider
|
|
||||||
import org.eclipse.milo.opcua.stack.client.security.DefaultClientCertificateValidator
|
import org.eclipse.milo.opcua.stack.client.security.DefaultClientCertificateValidator
|
||||||
import org.eclipse.milo.opcua.stack.core.security.DefaultTrustListManager
|
import org.eclipse.milo.opcua.stack.core.security.DefaultTrustListManager
|
||||||
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy
|
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy
|
||||||
@ -18,14 +17,14 @@ import java.nio.file.Path
|
|||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal fun <T:Any> T?.toOptional(): Optional<T> = if(this == null) Optional.empty() else Optional.of(this)
|
internal fun <T : Any> T?.toOptional(): Optional<T> = Optional.ofNullable(this)
|
||||||
|
|
||||||
|
|
||||||
internal fun Context.createOpcUaClient(
|
internal fun Context.createOpcUaClient(
|
||||||
endpointUrl: String, //"opc.tcp://localhost:12686/milo"
|
endpointUrl: String, //"opc.tcp://localhost:12686/milo"
|
||||||
securityPolicy: SecurityPolicy = SecurityPolicy.Basic256Sha256,
|
securityPolicy: SecurityPolicy = SecurityPolicy.Basic256Sha256,
|
||||||
identityProvider: IdentityProvider = AnonymousProvider(),
|
endpointFilter: (EndpointDescription?) -> Boolean = { securityPolicy.uri == it?.securityPolicyUri },
|
||||||
endpointFilter: (EndpointDescription?) -> Boolean = { securityPolicy.uri == it?.securityPolicyUri }
|
opcClientConfig: OpcUaClientConfigBuilder.() -> Unit,
|
||||||
): OpcUaClient {
|
): OpcUaClient {
|
||||||
|
|
||||||
val securityTempDir: Path = Paths.get(System.getProperty("java.io.tmpdir"), "client", "security")
|
val securityTempDir: Path = Paths.get(System.getProperty("java.io.tmpdir"), "client", "security")
|
||||||
@ -47,14 +46,15 @@ internal fun Context.createOpcUaClient(
|
|||||||
}
|
}
|
||||||
) { configBuilder: OpcUaClientConfigBuilder ->
|
) { configBuilder: OpcUaClientConfigBuilder ->
|
||||||
configBuilder
|
configBuilder
|
||||||
.setApplicationName(LocalizedText.english("Controls.kt"))
|
.setApplicationName(LocalizedText.english("Controls-kt"))
|
||||||
.setApplicationUri("urn:ru.mipt:npm:controls:opcua")
|
.setApplicationUri("urn:space.kscience:controls:opcua")
|
||||||
// .setKeyPair(loader.getClientKeyPair())
|
// .setKeyPair(loader.getClientKeyPair())
|
||||||
// .setCertificate(loader.getClientCertificate())
|
// .setCertificate(loader.getClientCertificate())
|
||||||
// .setCertificateChain(loader.getClientCertificateChain())
|
// .setCertificateChain(loader.getClientCertificateChain())
|
||||||
.setCertificateValidator(certificateValidator)
|
.setCertificateValidator(certificateValidator)
|
||||||
.setIdentityProvider(identityProvider)
|
.setIdentityProvider(AnonymousProvider())
|
||||||
.setRequestTimeout(uint(5000))
|
.setRequestTimeout(uint(5000))
|
||||||
|
.apply(opcClientConfig)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
// .apply {
|
// .apply {
|
||||||
|
@ -12,6 +12,7 @@ import org.eclipse.milo.opcua.sdk.server.api.ManagedNamespaceWithLifecycle
|
|||||||
import org.eclipse.milo.opcua.sdk.server.api.MonitoredItem
|
import org.eclipse.milo.opcua.sdk.server.api.MonitoredItem
|
||||||
import org.eclipse.milo.opcua.sdk.server.nodes.UaFolderNode
|
import org.eclipse.milo.opcua.sdk.server.nodes.UaFolderNode
|
||||||
import org.eclipse.milo.opcua.sdk.server.nodes.UaNode
|
import org.eclipse.milo.opcua.sdk.server.nodes.UaNode
|
||||||
|
import org.eclipse.milo.opcua.sdk.server.nodes.UaNodeContext
|
||||||
import org.eclipse.milo.opcua.sdk.server.nodes.UaVariableNode
|
import org.eclipse.milo.opcua.sdk.server.nodes.UaVariableNode
|
||||||
import org.eclipse.milo.opcua.sdk.server.util.SubscriptionModel
|
import org.eclipse.milo.opcua.sdk.server.util.SubscriptionModel
|
||||||
import org.eclipse.milo.opcua.stack.core.AttributeId
|
import org.eclipse.milo.opcua.stack.core.AttributeId
|
||||||
@ -27,7 +28,6 @@ import space.kscience.dataforge.meta.Meta
|
|||||||
import space.kscience.dataforge.meta.MetaSerializer
|
import space.kscience.dataforge.meta.MetaSerializer
|
||||||
import space.kscience.dataforge.meta.ValueType
|
import space.kscience.dataforge.meta.ValueType
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
|
|
||||||
|
|
||||||
@ -50,25 +50,7 @@ public class DeviceNameSpace(
|
|||||||
lifecycleManager.addLifecycle(subscription)
|
lifecycleManager.addLifecycle(subscription)
|
||||||
|
|
||||||
lifecycleManager.addStartupTask {
|
lifecycleManager.addStartupTask {
|
||||||
deviceManager.devices.forEach { (deviceName, device) ->
|
nodeContext.registerHub(deviceManager, Name.EMPTY)
|
||||||
val tokenAsString = deviceName.toString()
|
|
||||||
val deviceFolder = UaFolderNode(
|
|
||||||
this.nodeContext,
|
|
||||||
newNodeId(tokenAsString),
|
|
||||||
newQualifiedName(tokenAsString),
|
|
||||||
LocalizedText.english(tokenAsString)
|
|
||||||
)
|
|
||||||
deviceFolder.addReference(
|
|
||||||
Reference(
|
|
||||||
deviceFolder.nodeId,
|
|
||||||
Identifiers.Organizes,
|
|
||||||
Identifiers.ObjectsFolder.expanded(),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
deviceFolder.registerDeviceNodes(deviceName.asName(), device)
|
|
||||||
this.nodeManager.addNode(deviceFolder)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lifecycleManager.addLifecycle(object : Lifecycle {
|
lifecycleManager.addLifecycle(object : Lifecycle {
|
||||||
@ -88,7 +70,7 @@ public class DeviceNameSpace(
|
|||||||
|
|
||||||
|
|
||||||
val node: UaVariableNode = UaVariableNode.UaVariableNodeBuilder(nodeContext).apply {
|
val node: UaVariableNode = UaVariableNode.UaVariableNodeBuilder(nodeContext).apply {
|
||||||
//for now use DF path as id
|
//for now, use DF paths as ids
|
||||||
nodeId = newNodeId("${deviceName.tokens.joinToString("/")}/$propertyName")
|
nodeId = newNodeId("${deviceName.tokens.joinToString("/")}/$propertyName")
|
||||||
when {
|
when {
|
||||||
descriptor.readable && descriptor.writable -> {
|
descriptor.readable && descriptor.writable -> {
|
||||||
@ -161,15 +143,15 @@ public class DeviceNameSpace(
|
|||||||
}
|
}
|
||||||
//recursively add sub-devices
|
//recursively add sub-devices
|
||||||
if (device is DeviceHub) {
|
if (device is DeviceHub) {
|
||||||
registerHub(device, deviceName)
|
nodeContext.registerHub(device, deviceName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun UaNode.registerHub(hub: DeviceHub, namePrefix: Name) {
|
private fun UaNodeContext.registerHub(hub: DeviceHub, namePrefix: Name) {
|
||||||
hub.devices.forEach { (deviceName, device) ->
|
hub.devices.forEach { (deviceName, device) ->
|
||||||
val tokenAsString = deviceName.toString()
|
val tokenAsString = deviceName.toString()
|
||||||
val deviceFolder = UaFolderNode(
|
val deviceFolder = UaFolderNode(
|
||||||
this.nodeContext,
|
this,
|
||||||
newNodeId(tokenAsString),
|
newNodeId(tokenAsString),
|
||||||
newQualifiedName(tokenAsString),
|
newQualifiedName(tokenAsString),
|
||||||
LocalizedText.english(tokenAsString)
|
LocalizedText.english(tokenAsString)
|
||||||
|
@ -8,6 +8,7 @@ import space.kscience.controls.spec.DeviceSpec
|
|||||||
import space.kscience.controls.spec.doubleProperty
|
import space.kscience.controls.spec.doubleProperty
|
||||||
import space.kscience.controls.spec.read
|
import space.kscience.controls.spec.read
|
||||||
import space.kscience.dataforge.meta.transformations.MetaConverter
|
import space.kscience.dataforge.meta.transformations.MetaConverter
|
||||||
|
import kotlin.test.Ignore
|
||||||
|
|
||||||
class OpcUaClientTest {
|
class OpcUaClientTest {
|
||||||
class DemoOpcUaDevice(config: MiloConfiguration) : OpcUaDeviceBySpec<DemoOpcUaDevice>(DemoOpcUaDevice, config) {
|
class DemoOpcUaDevice(config: MiloConfiguration) : OpcUaDeviceBySpec<DemoOpcUaDevice>(DemoOpcUaDevice, config) {
|
||||||
@ -37,6 +38,7 @@ class OpcUaClientTest {
|
|||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
fun testReadDouble() = runTest {
|
fun testReadDouble() = runTest {
|
||||||
DemoOpcUaDevice.build().use{
|
DemoOpcUaDevice.build().use{
|
||||||
println(it.read(DemoOpcUaDevice.randomDouble))
|
println(it.read(DemoOpcUaDevice.randomDouble))
|
||||||
|
23
controls-pi/README.md
Normal file
23
controls-pi/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Module controls-pi
|
||||||
|
|
||||||
|
Utils to work with controls-kt on Raspberry pi
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## Artifact:
|
||||||
|
|
||||||
|
The Maven coordinates of this project are `space.kscience:controls-pi:0.2.0`.
|
||||||
|
|
||||||
|
**Gradle Kotlin DSL:**
|
||||||
|
```kotlin
|
||||||
|
repositories {
|
||||||
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("space.kscience:controls-pi:0.2.0")
|
||||||
|
}
|
||||||
|
```
|
28
controls-pi/api/controls-pi.api
Normal file
28
controls-pi/api/controls-pi.api
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
public final class space/kscience/controls/pi/PiPlugin : space/kscience/dataforge/context/AbstractPlugin {
|
||||||
|
public static final field Companion Lspace/kscience/controls/pi/PiPlugin$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun getPorts ()Lspace/kscience/controls/ports/Ports;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/pi/PiPlugin$Companion : space/kscience/dataforge/context/PluginFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/pi/PiPlugin;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/pi/PiSerialPort : space/kscience/controls/ports/AbstractPort {
|
||||||
|
public static final field Companion Lspace/kscience/controls/pi/PiSerialPort$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function0;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function0;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public final fun getSerialBuilder ()Lkotlin/jvm/functions/Function0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/pi/PiSerialPort$Companion : space/kscience/controls/ports/PortFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/Port;
|
||||||
|
public fun getType ()Ljava/lang/String;
|
||||||
|
public final fun open (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/controls/pi/PiSerialPort;
|
||||||
|
}
|
||||||
|
|
16
controls-pi/build.gradle.kts
Normal file
16
controls-pi/build.gradle.kts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
plugins {
|
||||||
|
id("space.kscience.gradle.jvm")
|
||||||
|
`maven-publish`
|
||||||
|
}
|
||||||
|
|
||||||
|
description = """
|
||||||
|
Utils to work with controls-kt on Raspberry pi
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
api(project(":controls-core"))
|
||||||
|
api("com.pi4j:pi4j-ktx:2.4.0") // Kotlin DSL
|
||||||
|
api("com.pi4j:pi4j-core:2.3.0")
|
||||||
|
api("com.pi4j:pi4j-plugin-raspberrypi:2.3.0")
|
||||||
|
api("com.pi4j:pi4j-plugin-pigpio:2.3.0")
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package space.kscience.controls.pi
|
||||||
|
|
||||||
|
import space.kscience.controls.ports.Ports
|
||||||
|
import space.kscience.dataforge.context.AbstractPlugin
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.context.PluginFactory
|
||||||
|
import space.kscience.dataforge.context.PluginTag
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
|
||||||
|
public class PiPlugin : AbstractPlugin() {
|
||||||
|
public val ports: Ports by require(Ports)
|
||||||
|
|
||||||
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
|
public companion object : PluginFactory<PiPlugin> {
|
||||||
|
|
||||||
|
override val tag: PluginTag = PluginTag("controls.ports.pi", group = PluginTag.DATAFORGE_GROUP)
|
||||||
|
|
||||||
|
override fun build(context: Context, meta: Meta): PiPlugin = PiPlugin()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package space.kscience.controls.pi
|
||||||
|
|
||||||
|
import com.pi4j.Pi4J
|
||||||
|
import com.pi4j.io.serial.Baud
|
||||||
|
import com.pi4j.io.serial.Serial
|
||||||
|
import com.pi4j.io.serial.SerialConfigBuilder
|
||||||
|
import com.pi4j.ktx.io.serial
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import space.kscience.controls.ports.AbstractPort
|
||||||
|
import space.kscience.controls.ports.Port
|
||||||
|
import space.kscience.controls.ports.PortFactory
|
||||||
|
import space.kscience.controls.ports.toArray
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.context.error
|
||||||
|
import space.kscience.dataforge.context.logger
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.meta.enum
|
||||||
|
import space.kscience.dataforge.meta.get
|
||||||
|
import space.kscience.dataforge.meta.string
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
public class PiSerialPort(
|
||||||
|
context: Context,
|
||||||
|
coroutineContext: CoroutineContext = context.coroutineContext,
|
||||||
|
public val serialBuilder: () -> Serial,
|
||||||
|
) : AbstractPort(context, coroutineContext) {
|
||||||
|
|
||||||
|
private val serial: Serial by lazy { serialBuilder() }
|
||||||
|
|
||||||
|
|
||||||
|
private val listenerJob = this.scope.launch(Dispatchers.IO) {
|
||||||
|
val buffer = ByteBuffer.allocate(1024)
|
||||||
|
while (isActive) {
|
||||||
|
try {
|
||||||
|
val num = serial.read(buffer)
|
||||||
|
if (num > 0) {
|
||||||
|
receive(buffer.toArray(num))
|
||||||
|
}
|
||||||
|
if (num < 0) cancel("The input channel is exhausted")
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
logger.error(ex) { "Channel read error" }
|
||||||
|
delay(1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun write(data: ByteArray): Unit = withContext(Dispatchers.IO) {
|
||||||
|
serial.write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
listenerJob.cancel()
|
||||||
|
serial.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
public companion object : PortFactory {
|
||||||
|
override val type: String get() = "pi"
|
||||||
|
|
||||||
|
public fun open(context: Context, device: String, block: SerialConfigBuilder.() -> Unit): PiSerialPort =
|
||||||
|
PiSerialPort(context) {
|
||||||
|
Pi4J.newAutoContext().serial(device, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(context: Context, meta: Meta): Port = PiSerialPort(context) {
|
||||||
|
val device: String = meta["device"].string ?: error("Device name not defined")
|
||||||
|
val baudRate: Baud = meta["baudRate"].enum<Baud>() ?: Baud._9600
|
||||||
|
Pi4J.newAutoContext().serial(device) {
|
||||||
|
baud8N1(baudRate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
23
controls-ports-ktor/README.md
Normal file
23
controls-ports-ktor/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Module controls-ports-ktor
|
||||||
|
|
||||||
|
Implementation of byte ports on top os ktor-io asynchronous API
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
## Artifact:
|
||||||
|
|
||||||
|
The Maven coordinates of this project are `space.kscience:controls-ports-ktor:0.2.0`.
|
||||||
|
|
||||||
|
**Gradle Kotlin DSL:**
|
||||||
|
```kotlin
|
||||||
|
repositories {
|
||||||
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("space.kscience:controls-ports-ktor:0.2.0")
|
||||||
|
}
|
||||||
|
```
|
47
controls-ports-ktor/api/controls-ports-ktor.api
Normal file
47
controls-ports-ktor/api/controls-ports-ktor.api
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
public final class space/kscience/controls/ports/KtorPortsPlugin : space/kscience/dataforge/context/AbstractPlugin {
|
||||||
|
public static final field Companion Lspace/kscience/controls/ports/KtorPortsPlugin$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/KtorPortsPlugin$Companion : space/kscience/dataforge/context/PluginFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/KtorPortsPlugin;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/KtorTcpPort : space/kscience/controls/ports/AbstractPort, java/io/Closeable {
|
||||||
|
public static final field Companion Lspace/kscience/controls/ports/KtorTcpPort$Companion;
|
||||||
|
public fun close ()V
|
||||||
|
public final fun getHost ()Ljava/lang/String;
|
||||||
|
public final fun getPort ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/KtorTcpPort$Companion : space/kscience/controls/ports/PortFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/Port;
|
||||||
|
public fun getType ()Ljava/lang/String;
|
||||||
|
public final fun open (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILkotlin/coroutines/CoroutineContext;)Lspace/kscience/controls/ports/KtorTcpPort;
|
||||||
|
public static synthetic fun open$default (Lspace/kscience/controls/ports/KtorTcpPort$Companion;Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lspace/kscience/controls/ports/KtorTcpPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/KtorUdpPort : space/kscience/controls/ports/AbstractPort, java/io/Closeable {
|
||||||
|
public static final field Companion Lspace/kscience/controls/ports/KtorUdpPort$Companion;
|
||||||
|
public fun close ()V
|
||||||
|
public final fun getLocalHost ()Ljava/lang/String;
|
||||||
|
public final fun getLocalPort ()Ljava/lang/Integer;
|
||||||
|
public final fun getRemoteHost ()Ljava/lang/String;
|
||||||
|
public final fun getRemotePort ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/ports/KtorUdpPort$Companion : space/kscience/controls/ports/PortFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/Port;
|
||||||
|
public fun getType ()Ljava/lang/String;
|
||||||
|
public final fun open (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILjava/lang/Integer;Ljava/lang/String;Lkotlin/coroutines/CoroutineContext;)Lspace/kscience/controls/ports/KtorUdpPort;
|
||||||
|
public static synthetic fun open$default (Lspace/kscience/controls/ports/KtorUdpPort$Companion;Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILjava/lang/Integer;Ljava/lang/String;Lkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lspace/kscience/controls/ports/KtorUdpPort;
|
||||||
|
}
|
||||||
|
|
21
controls-ports-ktor/build.gradle.kts
Normal file
21
controls-ports-ktor/build.gradle.kts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("space.kscience.gradle.jvm")
|
||||||
|
`maven-publish`
|
||||||
|
}
|
||||||
|
|
||||||
|
description = """
|
||||||
|
Implementation of byte ports on top os ktor-io asynchronous API
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
val ktorVersion: String by rootProject.extra
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(projects.controlsCore)
|
||||||
|
api("io.ktor:ktor-network:$ktorVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
readme{
|
||||||
|
maturity = Maturity.PROTOTYPE
|
||||||
|
}
|
@ -6,21 +6,22 @@ import space.kscience.dataforge.context.PluginFactory
|
|||||||
import space.kscience.dataforge.context.PluginTag
|
import space.kscience.dataforge.context.PluginTag
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.asName
|
||||||
|
|
||||||
public class KtorTcpPortPlugin : AbstractPlugin() {
|
public class KtorPortsPlugin : AbstractPlugin() {
|
||||||
|
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
override fun content(target: String): Map<Name, Any> = when(target){
|
override fun content(target: String): Map<Name, Any> = when (target) {
|
||||||
PortFactory.TYPE -> mapOf(Name.EMPTY to KtorTcpPort)
|
PortFactory.TYPE -> mapOf("tcp".asName() to KtorTcpPort, "udp".asName() to KtorUdpPort)
|
||||||
else -> emptyMap()
|
else -> emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object : PluginFactory<KtorTcpPortPlugin> {
|
public companion object : PluginFactory<KtorPortsPlugin> {
|
||||||
|
|
||||||
override val tag: PluginTag = PluginTag("controls.ports.serial", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag("controls.ports.ktor", group = PluginTag.DATAFORGE_GROUP)
|
||||||
|
|
||||||
override fun build(context: Context, meta: Meta): KtorTcpPortPlugin = KtorTcpPortPlugin()
|
override fun build(context: Context, meta: Meta): KtorPortsPlugin = KtorPortsPlugin()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
package space.kscience.controls.ports
|
||||||
|
|
||||||
|
import io.ktor.network.selector.ActorSelectorManager
|
||||||
|
import io.ktor.network.sockets.InetSocketAddress
|
||||||
|
import io.ktor.network.sockets.aSocket
|
||||||
|
import io.ktor.network.sockets.openReadChannel
|
||||||
|
import io.ktor.network.sockets.openWriteChannel
|
||||||
|
import io.ktor.utils.io.consumeEachBufferRange
|
||||||
|
import io.ktor.utils.io.core.Closeable
|
||||||
|
import io.ktor.utils.io.writeAvailable
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.meta.int
|
||||||
|
import space.kscience.dataforge.meta.number
|
||||||
|
import space.kscience.dataforge.meta.string
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
public class KtorUdpPort internal constructor(
|
||||||
|
context: Context,
|
||||||
|
public val remoteHost: String,
|
||||||
|
public val remotePort: Int,
|
||||||
|
public val localPort: Int? = null,
|
||||||
|
public val localHost: String = "localhost",
|
||||||
|
coroutineContext: CoroutineContext = context.coroutineContext,
|
||||||
|
) : AbstractPort(context, coroutineContext), Closeable {
|
||||||
|
|
||||||
|
override fun toString(): String = "port[udp:$remoteHost:$remotePort]"
|
||||||
|
|
||||||
|
private val futureSocket = scope.async {
|
||||||
|
aSocket(ActorSelectorManager(Dispatchers.IO)).udp().connect(
|
||||||
|
remoteAddress = InetSocketAddress(remoteHost, remotePort),
|
||||||
|
localAddress = localPort?.let { InetSocketAddress(localHost, localPort) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val writeChannel = scope.async {
|
||||||
|
futureSocket.await().openWriteChannel(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val listenerJob = scope.launch {
|
||||||
|
val input = futureSocket.await().openReadChannel()
|
||||||
|
input.consumeEachBufferRange { buffer, _ ->
|
||||||
|
val array = ByteArray(buffer.remaining())
|
||||||
|
buffer.get(array)
|
||||||
|
receive(array)
|
||||||
|
isActive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun write(data: ByteArray) {
|
||||||
|
writeChannel.await().writeAvailable(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
listenerJob.cancel()
|
||||||
|
futureSocket.cancel()
|
||||||
|
super.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
public companion object : PortFactory {
|
||||||
|
|
||||||
|
override val type: String = "udp"
|
||||||
|
|
||||||
|
public fun open(
|
||||||
|
context: Context,
|
||||||
|
remoteHost: String,
|
||||||
|
remotePort: Int,
|
||||||
|
localPort: Int? = null,
|
||||||
|
localHost: String = "localhost",
|
||||||
|
coroutineContext: CoroutineContext = context.coroutineContext,
|
||||||
|
): KtorUdpPort {
|
||||||
|
return KtorUdpPort(context, remoteHost, remotePort, localPort, localHost, coroutineContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(context: Context, meta: Meta): Port {
|
||||||
|
val remoteHost by meta.string { error("Remote host is not specified") }
|
||||||
|
val remotePort by meta.number { error("Remote port is not specified") }
|
||||||
|
val localHost: String? by meta.string()
|
||||||
|
val localPort: Int? by meta.int()
|
||||||
|
return open(context, remoteHost, remotePort.toInt(), localPort, localHost ?: "localhost")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,32 +1,23 @@
|
|||||||
# Module controls-serial
|
# Module controls-serial
|
||||||
|
|
||||||
|
Implementation of direct serial port communication with JSerialComm
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
## Artifact:
|
## Artifact:
|
||||||
|
|
||||||
The Maven coordinates of this project are `space.kscience:controls-serial:0.1.1-SNAPSHOT`.
|
The Maven coordinates of this project are `space.kscience:controls-serial:0.2.0`.
|
||||||
|
|
||||||
**Gradle Groovy:**
|
|
||||||
```groovy
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://repo.kotlin.link' }
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'space.kscience:controls-serial:0.1.1-SNAPSHOT'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Gradle Kotlin DSL:**
|
**Gradle Kotlin DSL:**
|
||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("space.kscience:controls-serial:0.1.1-SNAPSHOT")
|
implementation("space.kscience:controls-serial:0.2.0")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
29
controls-serial/api/controls-serial.api
Normal file
29
controls-serial/api/controls-serial.api
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
public final class space/kscience/controls/serial/JSerialCommPort : space/kscience/controls/ports/AbstractPort {
|
||||||
|
public static final field Companion Lspace/kscience/controls/serial/JSerialCommPort$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lcom/fazecast/jSerialComm/SerialPort;Lkotlin/coroutines/CoroutineContext;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lcom/fazecast/jSerialComm/SerialPort;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun close ()V
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/serial/JSerialCommPort$Companion : space/kscience/controls/ports/PortFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/ports/Port;
|
||||||
|
public fun getType ()Ljava/lang/String;
|
||||||
|
public final fun open (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;IIIILkotlin/coroutines/CoroutineContext;)Lspace/kscience/controls/serial/JSerialCommPort;
|
||||||
|
public static synthetic fun open$default (Lspace/kscience/controls/serial/JSerialCommPort$Companion;Lspace/kscience/dataforge/context/Context;Ljava/lang/String;IIIILkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lspace/kscience/controls/serial/JSerialCommPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/serial/SerialPortPlugin : space/kscience/dataforge/context/AbstractPlugin {
|
||||||
|
public static final field Companion Lspace/kscience/controls/serial/SerialPortPlugin$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/serial/SerialPortPlugin$Companion : space/kscience/dataforge/context/PluginFactory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/serial/SerialPortPlugin;
|
||||||
|
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,17 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.jvm")
|
id("space.kscience.gradle.jvm")
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description = "Implementation of direct serial port communication with JSerialComm"
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
api(project(":controls-core"))
|
api(project(":controls-core"))
|
||||||
implementation("org.scream3r:jssc:2.8.0")
|
implementation("com.fazecast:jSerialComm:2.10.3")
|
||||||
|
}
|
||||||
|
|
||||||
|
readme{
|
||||||
|
maturity = Maturity.EXPERIMENTAL
|
||||||
}
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,92 +0,0 @@
|
|||||||
package space.kscience.controls.serial
|
|
||||||
|
|
||||||
import jssc.SerialPort.*
|
|
||||||
import jssc.SerialPortEventListener
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,7 +13,7 @@ public class SerialPortPlugin : AbstractPlugin() {
|
|||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
override fun content(target: String): Map<Name, Any> = when(target){
|
override fun content(target: String): Map<Name, Any> = when(target){
|
||||||
PortFactory.TYPE -> mapOf(Name.EMPTY to SerialPort)
|
PortFactory.TYPE -> mapOf(Name.EMPTY to JSerialCommPort)
|
||||||
else -> emptyMap()
|
else -> emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,32 +1,23 @@
|
|||||||
# Module controls-server
|
# Module controls-server
|
||||||
|
|
||||||
A magix event loop server with web server for visualization.
|
A combined Magix event loop server with web server for visualization.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
## Artifact:
|
## Artifact:
|
||||||
|
|
||||||
The Maven coordinates of this project are `space.kscience:controls-server:0.1.1-SNAPSHOT`.
|
The Maven coordinates of this project are `space.kscience:controls-server:0.2.0`.
|
||||||
|
|
||||||
**Gradle Groovy:**
|
|
||||||
```groovy
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://repo.kotlin.link' }
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'space.kscience:controls-server:0.1.1-SNAPSHOT'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Gradle Kotlin DSL:**
|
**Gradle Kotlin DSL:**
|
||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("space.kscience:controls-server:0.1.1-SNAPSHOT")
|
implementation("space.kscience:controls-server:0.2.0")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
9
controls-server/api/controls-server.api
Normal file
9
controls-server/api/controls-server.api
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
public final class space/kscience/controls/server/DeviceWebServerKt {
|
||||||
|
public static final fun deviceManagerModule (Lio/ktor/server/application/Application;Lspace/kscience/controls/manager/DeviceManager;[Lspace/kscience/magix/api/MagixFlowPlugin;Ljava/util/Collection;Ljava/lang/String;I)V
|
||||||
|
public static synthetic fun deviceManagerModule$default (Lio/ktor/server/application/Application;Lspace/kscience/controls/manager/DeviceManager;[Lspace/kscience/magix/api/MagixFlowPlugin;Ljava/util/Collection;Ljava/lang/String;IILjava/lang/Object;)V
|
||||||
|
public static final fun getWEB_SERVER_TARGET ()Lspace/kscience/dataforge/names/Name;
|
||||||
|
public static final fun startDeviceServer (Lkotlinx/coroutines/CoroutineScope;Lspace/kscience/controls/manager/DeviceManager;ILjava/lang/String;)Lio/ktor/server/engine/ApplicationEngine;
|
||||||
|
public static synthetic fun startDeviceServer$default (Lkotlinx/coroutines/CoroutineScope;Lspace/kscience/controls/manager/DeviceManager;ILjava/lang/String;ILjava/lang/Object;)Lio/ktor/server/engine/ApplicationEngine;
|
||||||
|
public static final fun whenStarted (Lio/ktor/server/engine/ApplicationEngine;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,12 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.jvm")
|
id("space.kscience.gradle.jvm")
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
description = """
|
description = """
|
||||||
A magix event loop server with web server for visualization.
|
A combined Magix event loop server with web server for visualization.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
@ -12,7 +14,7 @@ val ktorVersion: String by rootProject.extra
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(projects.controlsCore)
|
implementation(projects.controlsCore)
|
||||||
implementation(projects.controlsKtorTcp)
|
implementation(projects.controlsPortsKtor)
|
||||||
implementation(projects.magix.magixServer)
|
implementation(projects.magix.magixServer)
|
||||||
implementation("io.ktor:ktor-server-cio:$ktorVersion")
|
implementation("io.ktor:ktor-server-cio:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-server-websockets:$ktorVersion")
|
implementation("io.ktor:ktor-server-websockets:$ktorVersion")
|
||||||
@ -21,3 +23,7 @@ dependencies {
|
|||||||
implementation("io.ktor:ktor-server-html-builder:$ktorVersion")
|
implementation("io.ktor:ktor-server-html-builder:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-server-status-pages:$ktorVersion")
|
implementation("io.ktor:ktor-server-status-pages:$ktorVersion")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readme{
|
||||||
|
maturity = Maturity.PROTOTYPE
|
||||||
|
}
|
@ -1,32 +1,23 @@
|
|||||||
# Module controls-storage
|
# Module controls-storage
|
||||||
|
|
||||||
|
An API for stand-alone Controls-kt device or a hub.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
## Artifact:
|
## Artifact:
|
||||||
|
|
||||||
The Maven coordinates of this project are `space.kscience:controls-storage:0.1.1-SNAPSHOT`.
|
The Maven coordinates of this project are `space.kscience:controls-storage:0.2.0`.
|
||||||
|
|
||||||
**Gradle Groovy:**
|
|
||||||
```groovy
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://repo.kotlin.link' }
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'space.kscience:controls-storage:0.1.1-SNAPSHOT'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Gradle Kotlin DSL:**
|
**Gradle Kotlin DSL:**
|
||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("space.kscience:controls-storage:0.1.1-SNAPSHOT")
|
implementation("space.kscience:controls-storage:0.2.0")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -5,6 +5,10 @@ plugins {
|
|||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
|
||||||
|
description = """
|
||||||
|
An API for stand-alone Controls-kt device or a hub.
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
kscience{
|
kscience{
|
||||||
jvm()
|
jvm()
|
||||||
js()
|
js()
|
||||||
@ -13,7 +17,7 @@ kscience{
|
|||||||
}
|
}
|
||||||
dependencies(jvmMain){
|
dependencies(jvmMain){
|
||||||
api(projects.magix.magixApi)
|
api(projects.magix.magixApi)
|
||||||
api(projects.controlsMagixClient)
|
api(projects.controlsMagix)
|
||||||
api(projects.magix.magixServer)
|
api(projects.magix.magixServer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,23 @@
|
|||||||
# Module controls-xodus
|
# Module controls-xodus
|
||||||
|
|
||||||
|
An implementation of controls-storage on top of JetBrains Xodus.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
## Artifact:
|
## Artifact:
|
||||||
|
|
||||||
The Maven coordinates of this project are `space.kscience:controls-xodus:0.1.1-SNAPSHOT`.
|
The Maven coordinates of this project are `space.kscience:controls-xodus:0.2.0`.
|
||||||
|
|
||||||
**Gradle Groovy:**
|
|
||||||
```groovy
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://repo.kotlin.link' }
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'space.kscience:controls-xodus:0.1.1-SNAPSHOT'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Gradle Kotlin DSL:**
|
**Gradle Kotlin DSL:**
|
||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("space.kscience:controls-xodus:0.1.1-SNAPSHOT")
|
implementation("space.kscience:controls-xodus:0.2.0")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -5,6 +5,10 @@ plugins {
|
|||||||
|
|
||||||
val xodusVersion: String by rootProject.extra
|
val xodusVersion: String by rootProject.extra
|
||||||
|
|
||||||
|
description = """
|
||||||
|
An implementation of controls-storage on top of JetBrains Xodus.
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.controlsStorage)
|
api(projects.controlsStorage)
|
||||||
implementation("org.jetbrains.xodus:xodus-entity-store:$xodusVersion")
|
implementation("org.jetbrains.xodus:xodus-entity-store:$xodusVersion")
|
||||||
|
77
demo/all-things/api/all-things.api
Normal file
77
demo/all-things/api/all-things.api
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
public final class space/kscience/controls/demo/DemoController : tornadofx/Controller, space/kscience/dataforge/context/ContextAware {
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public final fun getDevice ()Lspace/kscience/controls/demo/DemoDevice;
|
||||||
|
public final fun getMagixServer ()Lio/ktor/server/engine/ApplicationEngine;
|
||||||
|
public final fun getOpcUaServer ()Lorg/eclipse/milo/opcua/sdk/server/OpcUaServer;
|
||||||
|
public final fun getVisualizer ()Lio/ktor/server/engine/ApplicationEngine;
|
||||||
|
public final fun init ()V
|
||||||
|
public final fun setDevice (Lspace/kscience/controls/demo/DemoDevice;)V
|
||||||
|
public final fun setMagixServer (Lio/ktor/server/engine/ApplicationEngine;)V
|
||||||
|
public final fun setOpcUaServer (Lorg/eclipse/milo/opcua/sdk/server/OpcUaServer;)V
|
||||||
|
public final fun setVisualizer (Lio/ktor/server/engine/ApplicationEngine;)V
|
||||||
|
public final fun shutdown ()V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/DemoControllerApp : tornadofx/App {
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun start (Ljavafx/stage/Stage;)V
|
||||||
|
public fun stop ()V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/DemoControllerView : tornadofx/View {
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun getRoot ()Ljavafx/scene/Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/DemoControllerViewKt {
|
||||||
|
public static final fun main ()V
|
||||||
|
public static synthetic fun main ([Ljava/lang/String;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/DemoDevice : space/kscience/controls/spec/DeviceBySpec, space/kscience/controls/demo/IDemoDevice {
|
||||||
|
public static final field Companion Lspace/kscience/controls/demo/DemoDevice$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public fun cosValue ()D
|
||||||
|
public fun getCosScaleState ()D
|
||||||
|
public fun getSinScaleState ()D
|
||||||
|
public fun getTimeScaleState ()D
|
||||||
|
public fun setCosScaleState (D)V
|
||||||
|
public fun setSinScaleState (D)V
|
||||||
|
public fun setTimeScaleState (D)V
|
||||||
|
public fun sinValue ()D
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/DemoDevice$Companion : space/kscience/controls/spec/DeviceSpec, space/kscience/dataforge/context/Factory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/demo/DemoDevice;
|
||||||
|
public final fun getCoordinates ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getCos ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getCosScale ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getResetScale ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getSin ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getSinScale ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getTimeScale ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public synthetic fun onOpen (Lspace/kscience/controls/api/Device;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun onOpen (Lspace/kscience/controls/demo/IDemoDevice;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/DemoDeviceServerKt {
|
||||||
|
public static final fun startDemoDeviceServer (Lkotlinx/coroutines/CoroutineScope;Lspace/kscience/magix/api/MagixEndpoint;)Lio/ktor/server/engine/ApplicationEngine;
|
||||||
|
public static final fun updateFrom (Lspace/kscience/plotly/models/Trace;Ljava/lang/String;Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun updateXYFrom (Lspace/kscience/plotly/models/Trace;Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static final fun windowed (Lkotlinx/coroutines/flow/Flow;I)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/controls/demo/IDemoDevice : space/kscience/controls/api/Device {
|
||||||
|
public abstract fun cosValue ()D
|
||||||
|
public abstract fun getCosScaleState ()D
|
||||||
|
public abstract fun getSinScaleState ()D
|
||||||
|
public abstract fun getTimeScaleState ()D
|
||||||
|
public abstract fun setCosScaleState (D)V
|
||||||
|
public abstract fun setSinScaleState (D)V
|
||||||
|
public abstract fun setTimeScaleState (D)V
|
||||||
|
public abstract fun sinValue ()D
|
||||||
|
public fun time ()Ljava/time/Instant;
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ dependencies {
|
|||||||
implementation(projects.controlsCore)
|
implementation(projects.controlsCore)
|
||||||
//implementation(projects.controlsServer)
|
//implementation(projects.controlsServer)
|
||||||
implementation(projects.magix.magixServer)
|
implementation(projects.magix.magixServer)
|
||||||
implementation(projects.controlsMagixClient)
|
implementation(projects.controlsMagix)
|
||||||
implementation(projects.magix.magixRsocket)
|
implementation(projects.magix.magixRsocket)
|
||||||
implementation(projects.magix.magixZmq)
|
implementation(projects.magix.magixZmq)
|
||||||
implementation(projects.controlsOpcua)
|
implementation(projects.controlsOpcua)
|
||||||
|
@ -8,7 +8,7 @@ import javafx.stage.Stage
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.eclipse.milo.opcua.sdk.server.OpcUaServer
|
import org.eclipse.milo.opcua.sdk.server.OpcUaServer
|
||||||
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText
|
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText
|
||||||
import space.kscience.controls.client.connectToMagix
|
import space.kscience.controls.client.launchMagixService
|
||||||
import space.kscience.controls.demo.DemoDevice.Companion.cosScale
|
import space.kscience.controls.demo.DemoDevice.Companion.cosScale
|
||||||
import space.kscience.controls.demo.DemoDevice.Companion.sinScale
|
import space.kscience.controls.demo.DemoDevice.Companion.sinScale
|
||||||
import space.kscience.controls.demo.DemoDevice.Companion.timeScale
|
import space.kscience.controls.demo.DemoDevice.Companion.timeScale
|
||||||
@ -36,8 +36,9 @@ class DemoController : Controller(), ContextAware {
|
|||||||
var visualizer: ApplicationEngine? = null
|
var visualizer: ApplicationEngine? = null
|
||||||
var opcUaServer: OpcUaServer = OpcUaServer {
|
var opcUaServer: OpcUaServer = OpcUaServer {
|
||||||
setApplicationName(LocalizedText.english("space.kscience.controls.opcua"))
|
setApplicationName(LocalizedText.english("space.kscience.controls.opcua"))
|
||||||
|
|
||||||
endpoint {
|
endpoint {
|
||||||
setBindPort(9999)
|
setBindPort(4840)
|
||||||
//use default endpoint
|
//use default endpoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +59,7 @@ class DemoController : Controller(), ContextAware {
|
|||||||
)
|
)
|
||||||
//Launch a device client and connect it to the server
|
//Launch a device client and connect it to the server
|
||||||
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost")
|
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost")
|
||||||
deviceManager.connectToMagix(deviceEndpoint)
|
deviceManager.launchMagixService(deviceEndpoint)
|
||||||
//connect visualization to a magix endpoint
|
//connect visualization to a magix endpoint
|
||||||
val visualEndpoint = MagixEndpoint.rSocketWithWebSockets("localhost")
|
val visualEndpoint = MagixEndpoint.rSocketWithWebSockets("localhost")
|
||||||
visualizer = startDemoDeviceServer(visualEndpoint)
|
visualizer = startDemoDeviceServer(visualEndpoint)
|
||||||
|
@ -68,11 +68,10 @@ class DemoDevice(context: Context, meta: Meta) : DeviceBySpec<IDemoDevice>(Compa
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val resetScale by action(MetaConverter.meta, MetaConverter.meta) {
|
val resetScale by unitAction {
|
||||||
write(timeScale, 5000.0)
|
write(timeScale, 5000.0)
|
||||||
write(sinScale, 1.0)
|
write(sinScale, 1.0)
|
||||||
write(cosScale, 1.0)
|
write(cosScale, 1.0)
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun IDemoDevice.onOpen() {
|
override suspend fun IDemoDevice.onOpen() {
|
||||||
|
@ -7,7 +7,8 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.html.div
|
import kotlinx.html.div
|
||||||
import kotlinx.html.link
|
import kotlinx.html.link
|
||||||
import space.kscience.controls.api.PropertyChangedMessage
|
import space.kscience.controls.api.PropertyChangedMessage
|
||||||
import space.kscience.controls.client.controlsMagixFormat
|
import space.kscience.controls.client.magixFormat
|
||||||
|
import space.kscience.controls.manager.DeviceManager
|
||||||
import space.kscience.controls.spec.name
|
import space.kscience.controls.spec.name
|
||||||
import space.kscience.dataforge.meta.double
|
import space.kscience.dataforge.meta.double
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
@ -54,7 +55,7 @@ suspend fun Trace.updateXYFrom(flow: Flow<Iterable<Pair<Double, Double>>>) {
|
|||||||
|
|
||||||
fun CoroutineScope.startDemoDeviceServer(magixEndpoint: MagixEndpoint): ApplicationEngine {
|
fun CoroutineScope.startDemoDeviceServer(magixEndpoint: MagixEndpoint): ApplicationEngine {
|
||||||
//share subscription to a parse message only once
|
//share subscription to a parse message only once
|
||||||
val subscription = magixEndpoint.subscribe(controlsMagixFormat).shareIn(this, SharingStarted.Lazily)
|
val subscription = magixEndpoint.subscribe(DeviceManager.magixFormat).shareIn(this, SharingStarted.Lazily)
|
||||||
|
|
||||||
val sinFlow = subscription.mapNotNull { (_, payload) ->
|
val sinFlow = subscription.mapNotNull { (_, payload) ->
|
||||||
(payload as? PropertyChangedMessage)?.takeIf { it.property == DemoDevice.sin.name }
|
(payload as? PropertyChangedMessage)?.takeIf { it.property == DemoDevice.sin.name }
|
||||||
|
111
demo/car/api/car.api
Normal file
111
demo/car/api/car.api
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
public abstract interface class space/kscience/controls/demo/car/IVirtualCar : space/kscience/controls/api/Device {
|
||||||
|
public static final field Companion Lspace/kscience/controls/demo/car/IVirtualCar$Companion;
|
||||||
|
public abstract fun getAccelerationState ()Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public abstract fun getLocationState ()Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public abstract fun getSpeedState ()Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public abstract fun setAccelerationState (Lspace/kscience/controls/demo/car/Vector2D;)V
|
||||||
|
public abstract fun setLocationState (Lspace/kscience/controls/demo/car/Vector2D;)V
|
||||||
|
public abstract fun setSpeedState (Lspace/kscience/controls/demo/car/Vector2D;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/IVirtualCar$Companion : space/kscience/controls/spec/DeviceSpec {
|
||||||
|
public final fun getAcceleration ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getLocation ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getSpeed ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/MagixVirtualCar : space/kscience/controls/demo/car/VirtualCar {
|
||||||
|
public static final field Companion Lspace/kscience/controls/demo/car/MagixVirtualCar$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public fun open (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/MagixVirtualCar$Companion : space/kscience/dataforge/context/Factory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/demo/car/MagixVirtualCar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/Vector2D : space/kscience/dataforge/meta/MetaRepr {
|
||||||
|
public static final field CoordinatesMetaConverter Lspace/kscience/controls/demo/car/Vector2D$CoordinatesMetaConverter;
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun <init> (DD)V
|
||||||
|
public synthetic fun <init> (DDILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun component1 ()D
|
||||||
|
public final fun component2 ()D
|
||||||
|
public final fun copy (DD)Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/controls/demo/car/Vector2D;DDILjava/lang/Object;)Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public final fun div (D)Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getX ()D
|
||||||
|
public final fun getY ()D
|
||||||
|
public fun hashCode ()I
|
||||||
|
public final fun setX (D)V
|
||||||
|
public final fun setY (D)V
|
||||||
|
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/Vector2D$CoordinatesMetaConverter : space/kscience/dataforge/meta/transformations/MetaConverter {
|
||||||
|
public synthetic fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public synthetic fun objectToMeta (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun objectToMeta (Lspace/kscience/controls/demo/car/Vector2D;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class space/kscience/controls/demo/car/VirtualCar : space/kscience/controls/spec/DeviceBySpec, space/kscience/controls/demo/car/IVirtualCar {
|
||||||
|
public static final field Companion Lspace/kscience/controls/demo/car/VirtualCar$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public final fun applyForce-HG0u8IE (Lspace/kscience/controls/demo/car/Vector2D;J)V
|
||||||
|
public fun getAccelerationState ()Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public fun getLocationState ()Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public fun getSpeedState ()Lspace/kscience/controls/demo/car/Vector2D;
|
||||||
|
public fun open (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun setAccelerationState (Lspace/kscience/controls/demo/car/Vector2D;)V
|
||||||
|
public fun setLocationState (Lspace/kscience/controls/demo/car/Vector2D;)V
|
||||||
|
public fun setSpeedState (Lspace/kscience/controls/demo/car/Vector2D;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/VirtualCar$Companion : space/kscience/dataforge/context/Factory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/demo/car/VirtualCar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/VirtualCarController : tornadofx/Controller, space/kscience/dataforge/context/ContextAware {
|
||||||
|
public static final field Companion Lspace/kscience/controls/demo/car/VirtualCarController$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public final fun getMagixServer ()Lio/ktor/server/engine/ApplicationEngine;
|
||||||
|
public final fun getMagixVirtualCar ()Lspace/kscience/controls/demo/car/MagixVirtualCar;
|
||||||
|
public final fun getStorageEndpoint ()Lspace/kscience/magix/api/MagixEndpoint;
|
||||||
|
public final fun getVirtualCar ()Lspace/kscience/controls/demo/car/VirtualCar;
|
||||||
|
public final fun getXodusStorageJob ()Lkotlinx/coroutines/Job;
|
||||||
|
public final fun init ()V
|
||||||
|
public final fun setMagixServer (Lio/ktor/server/engine/ApplicationEngine;)V
|
||||||
|
public final fun setMagixVirtualCar (Lspace/kscience/controls/demo/car/MagixVirtualCar;)V
|
||||||
|
public final fun setStorageEndpoint (Lspace/kscience/magix/api/MagixEndpoint;)V
|
||||||
|
public final fun setVirtualCar (Lspace/kscience/controls/demo/car/VirtualCar;)V
|
||||||
|
public final fun setXodusStorageJob (Lkotlinx/coroutines/Job;)V
|
||||||
|
public final fun shutdown ()V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/VirtualCarController$Companion {
|
||||||
|
public final fun getDeviceEntityStorePath ()Ljava/nio/file/Path;
|
||||||
|
public final fun getMagixEntityStorePath ()Ljava/nio/file/Path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/VirtualCarControllerApp : tornadofx/App {
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun start (Ljavafx/stage/Stage;)V
|
||||||
|
public fun stop ()V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/VirtualCarControllerKt {
|
||||||
|
public static final fun main ()V
|
||||||
|
public static synthetic fun main ([Ljava/lang/String;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/car/VirtualCarControllerView : tornadofx/View {
|
||||||
|
public fun <init> ()V
|
||||||
|
public fun getRoot ()Ljavafx/scene/Parent;
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ dependencies {
|
|||||||
implementation(projects.magix.magixServer)
|
implementation(projects.magix.magixServer)
|
||||||
implementation(projects.magix.magixRsocket)
|
implementation(projects.magix.magixRsocket)
|
||||||
implementation(projects.magix.magixZmq)
|
implementation(projects.magix.magixZmq)
|
||||||
implementation(projects.controlsMagixClient)
|
implementation(projects.controlsMagix)
|
||||||
implementation(projects.controlsStorage.controlsXodus)
|
implementation(projects.controlsStorage.controlsXodus)
|
||||||
implementation(projects.magix.magixStorage.magixStorageXodus)
|
implementation(projects.magix.magixStorage.magixStorageXodus)
|
||||||
// implementation(projects.controlsMongo)
|
// implementation(projects.controlsMongo)
|
||||||
|
@ -2,7 +2,8 @@ package space.kscience.controls.demo.car
|
|||||||
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import space.kscience.controls.api.PropertyChangedMessage
|
import space.kscience.controls.api.PropertyChangedMessage
|
||||||
import space.kscience.controls.client.controlsMagixFormat
|
import space.kscience.controls.client.magixFormat
|
||||||
|
import space.kscience.controls.manager.DeviceManager
|
||||||
import space.kscience.controls.spec.write
|
import space.kscience.controls.spec.write
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.Factory
|
import space.kscience.dataforge.context.Factory
|
||||||
@ -18,7 +19,7 @@ import kotlin.time.ExperimentalTime
|
|||||||
class MagixVirtualCar(context: Context, meta: Meta) : VirtualCar(context, meta) {
|
class MagixVirtualCar(context: Context, meta: Meta) : VirtualCar(context, meta) {
|
||||||
|
|
||||||
private fun MagixEndpoint.launchMagixVirtualCarUpdate() = launch {
|
private fun MagixEndpoint.launchMagixVirtualCarUpdate() = launch {
|
||||||
subscribe(controlsMagixFormat).collect { (_, payload) ->
|
subscribe(DeviceManager.magixFormat).collect { (_, payload) ->
|
||||||
(payload as? PropertyChangedMessage)?.let { message ->
|
(payload as? PropertyChangedMessage)?.let { message ->
|
||||||
if (message.sourceDevice == Name.parse("virtual-car")) {
|
if (message.sourceDevice == Name.parse("virtual-car")) {
|
||||||
when (message.property) {
|
when (message.property) {
|
||||||
|
@ -8,7 +8,7 @@ import javafx.scene.layout.Priority
|
|||||||
import javafx.stage.Stage
|
import javafx.stage.Stage
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import space.kscience.controls.client.connectToMagix
|
import space.kscience.controls.client.launchMagixService
|
||||||
import space.kscience.controls.demo.car.IVirtualCar.Companion.acceleration
|
import space.kscience.controls.demo.car.IVirtualCar.Companion.acceleration
|
||||||
import space.kscience.controls.manager.DeviceManager
|
import space.kscience.controls.manager.DeviceManager
|
||||||
import space.kscience.controls.manager.install
|
import space.kscience.controls.manager.install
|
||||||
@ -63,7 +63,7 @@ class VirtualCarController : Controller(), ContextAware {
|
|||||||
//mongoStorageJob = deviceManager.storeMessages(DefaultAsynchronousMongoClientFactory)
|
//mongoStorageJob = deviceManager.storeMessages(DefaultAsynchronousMongoClientFactory)
|
||||||
//Launch device client and connect it to the server
|
//Launch device client and connect it to the server
|
||||||
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost")
|
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost")
|
||||||
deviceManager.connectToMagix(deviceEndpoint)
|
deviceManager.launchMagixService(deviceEndpoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
demo/echo/api/echo.api
Normal file
5
demo/echo/api/echo.api
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
public final class space/kscience/controls/demo/echo/MainKt {
|
||||||
|
public static final fun main (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun main ([Ljava/lang/String;)V
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ private suspend fun MagixEndpoint.collectEcho(scope: CoroutineScope, n: Int) {
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
subscribe(
|
subscribe(
|
||||||
MagixMessageFilter(
|
MagixMessageFilter(
|
||||||
origin = listOf("loop")
|
source = listOf("loop")
|
||||||
)
|
)
|
||||||
).collect { message ->
|
).collect { message ->
|
||||||
if (message.id?.endsWith(".response") == true) {
|
if (message.id?.endsWith(".response") == true) {
|
||||||
@ -44,8 +44,8 @@ private suspend fun MagixEndpoint.collectEcho(scope: CoroutineScope, n: Int) {
|
|||||||
MagixMessage(
|
MagixMessage(
|
||||||
format = "test",
|
format = "test",
|
||||||
payload = JsonObject(emptyMap()),
|
payload = JsonObject(emptyMap()),
|
||||||
origin = "test",
|
sourceEndpoint = "test",
|
||||||
target = "loop",
|
targetEndpoint = "loop",
|
||||||
id = it.toString()
|
id = it.toString()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -60,14 +60,14 @@ private suspend fun MagixEndpoint.collectEcho(scope: CoroutineScope, n: Int) {
|
|||||||
@OptIn(ExperimentalTime::class)
|
@OptIn(ExperimentalTime::class)
|
||||||
suspend fun main(): Unit = coroutineScope {
|
suspend fun main(): Unit = coroutineScope {
|
||||||
launch(Dispatchers.Default) {
|
launch(Dispatchers.Default) {
|
||||||
val server = startMagixServer(MagixFlowPlugin { _, flow ->
|
val server = startMagixServer(MagixFlowPlugin { _, flow, send ->
|
||||||
val logger = LoggerFactory.getLogger("echo")
|
val logger = LoggerFactory.getLogger("echo")
|
||||||
//echo each message
|
//echo each message
|
||||||
flow.onEach { message ->
|
flow.onEach { message ->
|
||||||
if (message.parentId == null) {
|
if (message.parentId == null) {
|
||||||
val m = message.copy(origin = "loop", parentId = message.id, id = message.id + ".response")
|
val m = message.copy(sourceEndpoint = "loop", parentId = message.id, id = message.id + ".response")
|
||||||
logger.info(m.toString())
|
logger.info(m.toString())
|
||||||
flow.emit(m)
|
send(m)
|
||||||
}
|
}
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
})
|
})
|
||||||
|
7
demo/magix-demo/api/magix-demo.api
Normal file
7
demo/magix-demo/api/magix-demo.api
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
public final class ZmqKt {
|
||||||
|
public static final fun main (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun main ([Ljava/lang/String;)V
|
||||||
|
public static final fun sendJson (Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun sendJson$default (Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
18
demo/many-devices/api/many-devices.api
Normal file
18
demo/many-devices/api/many-devices.api
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
public final class space/kscience/controls/demo/MassDevice : space/kscience/controls/spec/DeviceBySpec {
|
||||||
|
public static final field Companion Lspace/kscience/controls/demo/MassDevice$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/MassDevice$Companion : space/kscience/controls/spec/DeviceSpec, space/kscience/dataforge/context/Factory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/controls/demo/MassDevice;
|
||||||
|
public final fun getValue ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public synthetic fun onOpen (Lspace/kscience/controls/api/Device;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun onOpen (Lspace/kscience/controls/demo/MassDevice;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/controls/demo/MassDeviceKt {
|
||||||
|
public static final fun main (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun main ([Ljava/lang/String;)V
|
||||||
|
}
|
||||||
|
|
@ -14,12 +14,12 @@ val rsocketVersion: String by rootProject.extra
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(projects.magix.magixServer)
|
implementation(projects.magix.magixServer)
|
||||||
implementation(projects.controlsMagixClient)
|
implementation(projects.controlsMagix)
|
||||||
implementation(projects.magix.magixRsocket)
|
implementation(projects.magix.magixRsocket)
|
||||||
implementation(projects.magix.magixZmq)
|
implementation(projects.magix.magixZmq)
|
||||||
|
|
||||||
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
||||||
implementation("space.kscience:plotlykt-server:0.5.3")
|
implementation("space.kscience:plotlykt-server:0.6.0")
|
||||||
implementation(spclibs.logback.classic)
|
implementation(spclibs.logback.classic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package space.kscience.controls.demo
|
package space.kscience.controls.demo
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.datetime.Clock
|
import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.Instant
|
import space.kscience.controls.client.launchMagixService
|
||||||
import space.kscience.controls.client.connectToMagix
|
import space.kscience.controls.client.magixFormat
|
||||||
import space.kscience.controls.client.controlsMagixFormat
|
|
||||||
import space.kscience.controls.manager.DeviceManager
|
import space.kscience.controls.manager.DeviceManager
|
||||||
import space.kscience.controls.manager.install
|
import space.kscience.controls.manager.install
|
||||||
import space.kscience.controls.spec.*
|
import space.kscience.controls.spec.*
|
||||||
@ -21,7 +19,8 @@ import space.kscience.dataforge.meta.get
|
|||||||
import space.kscience.dataforge.meta.int
|
import space.kscience.dataforge.meta.int
|
||||||
import space.kscience.magix.api.MagixEndpoint
|
import space.kscience.magix.api.MagixEndpoint
|
||||||
import space.kscience.magix.api.subscribe
|
import space.kscience.magix.api.subscribe
|
||||||
import space.kscience.magix.rsocket.rSocketStreamWithTcp
|
import space.kscience.magix.rsocket.rSocketWithTcp
|
||||||
|
import space.kscience.magix.rsocket.rSocketWithWebSockets
|
||||||
import space.kscience.magix.server.RSocketMagixFlowPlugin
|
import space.kscience.magix.server.RSocketMagixFlowPlugin
|
||||||
import space.kscience.magix.server.startMagixServer
|
import space.kscience.magix.server.startMagixServer
|
||||||
import space.kscience.plotly.Plotly
|
import space.kscience.plotly.Plotly
|
||||||
@ -31,8 +30,10 @@ import space.kscience.plotly.plot
|
|||||||
import space.kscience.plotly.server.PlotlyUpdateMode
|
import space.kscience.plotly.server.PlotlyUpdateMode
|
||||||
import space.kscience.plotly.server.serve
|
import space.kscience.plotly.server.serve
|
||||||
import space.kscience.plotly.server.show
|
import space.kscience.plotly.server.show
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import space.kscince.magix.zmq.ZmqMagixFlowPlugin
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.ZERO
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
|
|
||||||
@ -48,25 +49,27 @@ class MassDevice(context: Context, meta: Meta) : DeviceBySpec<MassDevice>(MassDe
|
|||||||
val value by doubleProperty { randomValue }
|
val value by doubleProperty { randomValue }
|
||||||
|
|
||||||
override suspend fun MassDevice.onOpen() {
|
override suspend fun MassDevice.onOpen() {
|
||||||
doRecurring(100.milliseconds) {
|
doRecurring((meta["delay"].int ?: 10).milliseconds) {
|
||||||
read(value)
|
read(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() {
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
suspend fun main() {
|
||||||
val context = Context("Mass")
|
val context = Context("Mass")
|
||||||
|
|
||||||
context.startMagixServer(
|
context.startMagixServer(
|
||||||
RSocketMagixFlowPlugin(),
|
RSocketMagixFlowPlugin(),
|
||||||
// ZmqMagixFlowPlugin()
|
ZmqMagixFlowPlugin()
|
||||||
)
|
)
|
||||||
|
|
||||||
val numDevices = 100
|
val numDevices = 100
|
||||||
|
|
||||||
context.launch(Dispatchers.IO) {
|
|
||||||
repeat(numDevices) {
|
repeat(numDevices) {
|
||||||
|
context.launch(newFixedThreadPoolContext(2, "Device${it}")) {
|
||||||
|
delay(1)
|
||||||
val deviceContext = Context("Device${it}") {
|
val deviceContext = Context("Device${it}") {
|
||||||
plugin(DeviceManager)
|
plugin(DeviceManager)
|
||||||
}
|
}
|
||||||
@ -76,8 +79,8 @@ fun main() {
|
|||||||
deviceManager.install("device$it", MassDevice)
|
deviceManager.install("device$it", MassDevice)
|
||||||
|
|
||||||
val endpointId = "device$it"
|
val endpointId = "device$it"
|
||||||
val deviceEndpoint = MagixEndpoint.rSocketStreamWithTcp("localhost")
|
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost")
|
||||||
deviceManager.connectToMagix(deviceEndpoint, endpointId)
|
deviceManager.launchMagixService(deviceEndpoint, endpointId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,23 +91,36 @@ fun main() {
|
|||||||
plot(renderer = container) {
|
plot(renderer = container) {
|
||||||
layout {
|
layout {
|
||||||
title = "Latest event"
|
title = "Latest event"
|
||||||
|
xaxis.title = "Device number"
|
||||||
|
yaxis.title = "Maximum latency in ms"
|
||||||
}
|
}
|
||||||
bar {
|
bar {
|
||||||
launch(Dispatchers.Default){
|
launch(Dispatchers.IO) {
|
||||||
val monitorEndpoint = MagixEndpoint.rSocketStreamWithTcp("localhost")
|
val monitorEndpoint = MagixEndpoint.rSocketWithWebSockets("localhost")
|
||||||
|
|
||||||
val latest = ConcurrentHashMap<String, Instant>()
|
val mutex = Mutex()
|
||||||
|
|
||||||
monitorEndpoint.subscribe(controlsMagixFormat).onEach { (magixMessage, payload) ->
|
val latest = HashMap<String, Duration>()
|
||||||
latest[magixMessage.origin] = payload.time ?: Clock.System.now()
|
val max = HashMap<String, Duration>()
|
||||||
|
|
||||||
|
monitorEndpoint.subscribe(DeviceManager.magixFormat).onEach { (magixMessage, payload) ->
|
||||||
|
mutex.withLock {
|
||||||
|
val delay = Clock.System.now() - payload.time!!
|
||||||
|
latest[magixMessage.sourceEndpoint] = Clock.System.now() - payload.time!!
|
||||||
|
max[magixMessage.sourceEndpoint] =
|
||||||
|
maxOf(delay, max[magixMessage.sourceEndpoint] ?: ZERO)
|
||||||
|
}
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
|
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
delay(200)
|
delay(200)
|
||||||
val now = Clock.System.now()
|
mutex.withLock {
|
||||||
val sorted = latest.mapKeys { it.key.substring(6).toInt() }.toSortedMap()
|
val sorted = max.mapKeys { it.key.substring(6).toInt() }.toSortedMap()
|
||||||
|
latest.clear()
|
||||||
|
max.clear()
|
||||||
x.numbers = sorted.keys
|
x.numbers = sorted.keys
|
||||||
y.numbers = sorted.values.map { now.minus(it).inWholeMilliseconds / 1000.0 }
|
y.numbers = sorted.values.map { it.inWholeMilliseconds / 1000.0 + 0.0001 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
demo/mks-pdr900/api/mks-pdr900.api
Normal file
28
demo/mks-pdr900/api/mks-pdr900.api
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
public final class center/sciprog/devices/mks/MksPdr900Device : space/kscience/controls/spec/DeviceBySpec {
|
||||||
|
public static final field Companion Lcenter/sciprog/devices/mks/MksPdr900Device$Companion;
|
||||||
|
public static final field DEFAULT_CHANNEL I
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)V
|
||||||
|
public final fun readChannelData (ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun readPowerOn (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun writePowerOn (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class center/sciprog/devices/mks/MksPdr900Device$Companion : space/kscience/controls/spec/DeviceSpec, space/kscience/dataforge/context/Factory {
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lcenter/sciprog/devices/mks/MksPdr900Device;
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public final fun getChannel ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getError ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getPowerOn ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getValue ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public fun onClose (Lcenter/sciprog/devices/mks/MksPdr900Device;)V
|
||||||
|
public synthetic fun onClose (Lspace/kscience/controls/api/Device;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class center/sciprog/devices/mks/NullableStringMetaConverter : space/kscience/dataforge/meta/transformations/MetaConverter {
|
||||||
|
public static final field INSTANCE Lcenter/sciprog/devices/mks/NullableStringMetaConverter;
|
||||||
|
public synthetic fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun metaToObject (Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/String;
|
||||||
|
public synthetic fun objectToMeta (Ljava/lang/Object;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
public fun objectToMeta (Ljava/lang/String;)Lspace/kscience/dataforge/meta/Meta;
|
||||||
|
}
|
||||||
|
|
@ -17,5 +17,5 @@ val ktorVersion: String by rootProject.extra
|
|||||||
val dataforgeVersion: String by extra
|
val dataforgeVersion: String by extra
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(projects.controlsKtorTcp)
|
implementation(projects.controlsPortsKtor)
|
||||||
}
|
}
|
||||||
|
115
demo/motors/api/motors.api
Normal file
115
demo/motors/api/motors.api
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/FxDevicePropertiesKt {
|
||||||
|
public static final fun fxProperty (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/DevicePropertySpec;)Ljavafx/beans/property/ReadOnlyProperty;
|
||||||
|
public static final fun fxProperty (Lspace/kscience/controls/api/Device;Lspace/kscience/controls/spec/WritableDevicePropertySpec;)Ljavafx/beans/property/Property;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiDebugServerKt {
|
||||||
|
public static final fun getExceptionHandler ()Lkotlinx/coroutines/CoroutineExceptionHandler;
|
||||||
|
public static final fun launchPiDebugServer (Lspace/kscience/dataforge/context/Context;ILjava/util/List;)Lkotlinx/coroutines/Job;
|
||||||
|
public static final fun main ()V
|
||||||
|
public static synthetic fun main ([Ljava/lang/String;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp : tornadofx/App {
|
||||||
|
public fun <init> ()V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterAppKt {
|
||||||
|
public static final fun axisPane (Ljavafx/scene/Parent;Ljava/util/Map;Lkotlinx/coroutines/CoroutineScope;)V
|
||||||
|
public static final fun main ()V
|
||||||
|
public static synthetic fun main ([Ljava/lang/String;)V
|
||||||
|
public static final fun piMotionMasterAxis (Ljavafx/scene/layout/VBox;Ljava/lang/String;Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice$Axis;Lkotlinx/coroutines/CoroutineScope;)Ljavafx/scene/layout/HBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterController : tornadofx/Controller {
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
public final fun getDeviceManager ()Lspace/kscience/controls/manager/DeviceManager;
|
||||||
|
public final fun getMotionMaster ()Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice : space/kscience/controls/spec/DeviceBySpec, space/kscience/controls/api/DeviceHub {
|
||||||
|
public static final field Companion Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/controls/ports/PortFactory;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Lspace/kscience/controls/ports/PortFactory;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun connect (Ljava/lang/String;I)V
|
||||||
|
public final fun disconnect ()V
|
||||||
|
public final fun getAxes ()Ljava/util/Map;
|
||||||
|
public fun getDevices ()Ljava/util/Map;
|
||||||
|
public final fun getErrorCode (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun getTimeoutValue-UwyO8pc ()J
|
||||||
|
public final fun setTimeoutValue-LRDsOJo (J)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice$Axis : space/kscience/controls/spec/DeviceBySpec {
|
||||||
|
public static final field Companion Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice$Axis$Companion;
|
||||||
|
public fun <init> (Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice;Ljava/lang/String;)V
|
||||||
|
public final fun getAxisId ()Ljava/lang/String;
|
||||||
|
public final fun getMm ()Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice;
|
||||||
|
public final fun move (DLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice$Axis$Companion : space/kscience/controls/spec/DeviceSpec {
|
||||||
|
public final fun getClosedLoop ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getEnabled ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getHalt ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getMaxPosition ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getMinPosition ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getMove ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getMoveToReference ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getOnTarget ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getOpenLoopTarget ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getPosition ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getReference ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getTargetPosition ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
public final fun getVelocity ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice$Companion : space/kscience/controls/spec/DeviceSpec, space/kscience/dataforge/context/Factory {
|
||||||
|
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
|
||||||
|
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice;
|
||||||
|
public final fun getConnect ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getConnected ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getDisconnect ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getFirmwareVersion ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getIdentity ()Lspace/kscience/controls/spec/DevicePropertySpec;
|
||||||
|
public final fun getInitialize ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getStop ()Lspace/kscience/controls/spec/DeviceActionSpec;
|
||||||
|
public final fun getTimeout ()Lspace/kscience/controls/spec/WritableDevicePropertySpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterView : tornadofx/View {
|
||||||
|
public fun <init> ()V
|
||||||
|
public final fun getDevice ()Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterDevice;
|
||||||
|
public fun getRoot ()Ljavafx/scene/Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterVirtualDevice : ru/mipt/npm/devices/pimotionmaster/VirtualDevice, space/kscience/dataforge/context/ContextAware {
|
||||||
|
public static final field Companion Lru/mipt/npm/devices/pimotionmaster/PiMotionMasterVirtualDevice$Companion;
|
||||||
|
public fun <init> (Lspace/kscience/dataforge/context/Context;Ljava/util/List;Lkotlinx/coroutines/CoroutineScope;)V
|
||||||
|
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Ljava/util/List;Lkotlinx/coroutines/CoroutineScope;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun getContext ()Lspace/kscience/dataforge/context/Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/PiMotionMasterVirtualDevice$Companion {
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class ru/mipt/npm/devices/pimotionmaster/VirtualDevice : space/kscience/controls/api/Socket {
|
||||||
|
public fun <init> (Lkotlinx/coroutines/CoroutineScope;)V
|
||||||
|
public fun close ()V
|
||||||
|
protected abstract fun evaluateRequest ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun getScope ()Lkotlinx/coroutines/CoroutineScope;
|
||||||
|
public fun isOpen ()Z
|
||||||
|
public fun receiving ()Lkotlinx/coroutines/flow/Flow;
|
||||||
|
protected final fun respond ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
protected final fun respondInFuture-VtjQ1oo (JLkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/Job;
|
||||||
|
public synthetic fun send (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public fun send ([BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
protected fun transformRequests (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ru/mipt/npm/devices/pimotionmaster/VirtualPort : space/kscience/controls/ports/AbstractPort {
|
||||||
|
public fun <init> (Lru/mipt/npm/devices/pimotionmaster/VirtualDevice;Lspace/kscience/dataforge/context/Context;)V
|
||||||
|
public fun close ()V
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ val ktorVersion: String by rootProject.extra
|
|||||||
val dataforgeVersion: String by extra
|
val dataforgeVersion: String by extra
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":controls-ktor-tcp"))
|
implementation(project(":controls-ports-ktor"))
|
||||||
implementation(project(":controls-magix-client"))
|
implementation(projects.controlsMagix)
|
||||||
implementation("no.tornado:tornadofx:1.7.20")
|
implementation("no.tornado:tornadofx:1.7.20")
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ class PiMotionMasterDevice(
|
|||||||
send("STP")
|
send("STP")
|
||||||
}
|
}
|
||||||
|
|
||||||
val connect by metaAction(descriptorBuilder = {
|
val connect by action(MetaConverter.meta, MetaConverter.unit, descriptorBuilder = {
|
||||||
info = "Connect to specific port and initialize axis"
|
info = "Connect to specific port and initialize axis"
|
||||||
}) { portSpec ->
|
}) { portSpec ->
|
||||||
//Clear current actions if present
|
//Clear current actions if present
|
||||||
@ -171,11 +171,10 @@ class PiMotionMasterDevice(
|
|||||||
}
|
}
|
||||||
//Update port
|
//Update port
|
||||||
//address = portSpec.node
|
//address = portSpec.node
|
||||||
port = portFactory(portSpec ?: Meta.EMPTY, context)
|
port = portFactory(portSpec, context)
|
||||||
updateLogical(connected, true)
|
updateLogical(connected, true)
|
||||||
// connector.open()
|
// connector.open()
|
||||||
//Initialize axes
|
//Initialize axes
|
||||||
if (portSpec != null) {
|
|
||||||
val idn = read(identity)
|
val idn = read(identity)
|
||||||
failIfError { "Can't connect to $portSpec. Error code: $it" }
|
failIfError { "Can't connect to $portSpec. Error code: $it" }
|
||||||
logger.info { "Connected to $idn on $portSpec" }
|
logger.info { "Connected to $idn on $portSpec" }
|
||||||
@ -188,19 +187,16 @@ class PiMotionMasterDevice(
|
|||||||
execute(initialize)
|
execute(initialize)
|
||||||
failIfError()
|
failIfError()
|
||||||
}
|
}
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val disconnect by metaAction({
|
val disconnect by unitAction({
|
||||||
info = "Disconnect the program from the device if it is connected"
|
info = "Disconnect the program from the device if it is connected"
|
||||||
}) {
|
}) {
|
||||||
port?.let{
|
port?.let {
|
||||||
execute(stop)
|
execute(stop)
|
||||||
it.close()
|
it.close()
|
||||||
}
|
}
|
||||||
port = null
|
port = null
|
||||||
updateLogical(connected, false)
|
updateLogical(connected, false)
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -212,7 +208,7 @@ class PiMotionMasterDevice(
|
|||||||
|
|
||||||
class Axis(
|
class Axis(
|
||||||
val mm: PiMotionMasterDevice,
|
val mm: PiMotionMasterDevice,
|
||||||
val axisId: String
|
val axisId: String,
|
||||||
) : DeviceBySpec<Axis>(Axis, mm.context) {
|
) : DeviceBySpec<Axis>(Axis, mm.context) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,7 +240,7 @@ class PiMotionMasterDevice(
|
|||||||
|
|
||||||
private fun axisBooleanProperty(
|
private fun axisBooleanProperty(
|
||||||
command: String,
|
command: String,
|
||||||
descriptorBuilder: PropertyDescriptor.() -> Unit = {}
|
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
||||||
) = booleanProperty(
|
) = booleanProperty(
|
||||||
read = {
|
read = {
|
||||||
readAxisBoolean("$command?")
|
readAxisBoolean("$command?")
|
||||||
@ -257,7 +253,7 @@ class PiMotionMasterDevice(
|
|||||||
|
|
||||||
private fun axisNumberProperty(
|
private fun axisNumberProperty(
|
||||||
command: String,
|
command: String,
|
||||||
descriptorBuilder: PropertyDescriptor.() -> Unit = {}
|
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
|
||||||
) = doubleProperty(
|
) = doubleProperty(
|
||||||
read = {
|
read = {
|
||||||
mm.requestAndParse("$command?", axisId)[axisId]?.toDoubleOrNull()
|
mm.requestAndParse("$command?", axisId)[axisId]?.toDoubleOrNull()
|
||||||
@ -334,11 +330,11 @@ class PiMotionMasterDevice(
|
|||||||
info = "Velocity value for closed-loop operation"
|
info = "Velocity value for closed-loop operation"
|
||||||
}
|
}
|
||||||
|
|
||||||
val move by metaAction {
|
val move by action(MetaConverter.meta, MetaConverter.unit) {
|
||||||
val target = it.double ?: it?.get("target").double ?: error("Unacceptable target value $it")
|
val target = it.double ?: it["target"].double ?: error("Unacceptable target value $it")
|
||||||
write(closedLoop, true)
|
write(closedLoop, true)
|
||||||
//optionally set velocity
|
//optionally set velocity
|
||||||
it?.get("velocity").double?.let { v ->
|
it["velocity"].double?.let { v ->
|
||||||
write(velocity, v)
|
write(velocity, v)
|
||||||
}
|
}
|
||||||
write(targetPosition, target)
|
write(targetPosition, target)
|
||||||
@ -347,7 +343,6 @@ class PiMotionMasterDevice(
|
|||||||
read(position)
|
read(position)
|
||||||
delay(200)
|
delay(200)
|
||||||
}
|
}
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ import tornadofx.*
|
|||||||
/**
|
/**
|
||||||
* Bind a FX property to a device property with a given [spec]
|
* Bind a FX property to a device property with a given [spec]
|
||||||
*/
|
*/
|
||||||
fun <D : Device, T : Any> Device.fxProperty(
|
fun <D : Device, T : Any> D.fxProperty(
|
||||||
spec: DevicePropertySpec<D, T>
|
spec: DevicePropertySpec<D, T>,
|
||||||
): ReadOnlyProperty<T> = object : ObjectPropertyBase<T>() {
|
): ReadOnlyProperty<T> = object : ObjectPropertyBase<T>() {
|
||||||
override fun getBean(): Any = this
|
override fun getBean(): Any = this
|
||||||
override fun getName(): String = spec.name
|
override fun getName(): String = spec.name
|
||||||
@ -21,7 +21,6 @@ fun <D : Device, T : Any> Device.fxProperty(
|
|||||||
init {
|
init {
|
||||||
//Read incoming changes
|
//Read incoming changes
|
||||||
onPropertyChange(spec) {
|
onPropertyChange(spec) {
|
||||||
if (it != null) {
|
|
||||||
runLater {
|
runLater {
|
||||||
try {
|
try {
|
||||||
set(it)
|
set(it)
|
||||||
@ -29,9 +28,6 @@ fun <D : Device, T : Any> Device.fxProperty(
|
|||||||
logger.info { "Failed to set property $name to $it" }
|
logger.info { "Failed to set property $name to $it" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
invalidated()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,7 +40,6 @@ fun <D : Device, T : Any> D.fxProperty(spec: WritableDevicePropertySpec<D, T>):
|
|||||||
init {
|
init {
|
||||||
//Read incoming changes
|
//Read incoming changes
|
||||||
onPropertyChange(spec) {
|
onPropertyChange(spec) {
|
||||||
if (it != null) {
|
|
||||||
runLater {
|
runLater {
|
||||||
try {
|
try {
|
||||||
set(it)
|
set(it)
|
||||||
@ -52,9 +47,6 @@ fun <D : Device, T : Any> D.fxProperty(spec: WritableDevicePropertySpec<D, T>):
|
|||||||
logger.info { "Failed to set property $name to $it" }
|
logger.info { "Failed to set property $name to $it" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
invalidated()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange { newValue ->
|
onChange { newValue ->
|
||||||
|
@ -7,4 +7,7 @@ org.gradle.parallel=true
|
|||||||
publishing.github=false
|
publishing.github=false
|
||||||
publishing.sonatype=false
|
publishing.sonatype=false
|
||||||
|
|
||||||
toolsVersion=0.14.6-kotlin-1.8.20
|
org.gradle.configureondemand=true
|
||||||
|
org.gradle.jvmargs=-Xmx4096m
|
||||||
|
|
||||||
|
toolsVersion=0.14.10-kotlin-1.9.0
|
@ -1,4 +0,0 @@
|
|||||||
# Module magix
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
subprojects{
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +1,23 @@
|
|||||||
# Module magix-api
|
# Module magix-api
|
||||||
|
|
||||||
|
A kotlin API for magix standard and some zero-dependency magix services
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
## Artifact:
|
## Artifact:
|
||||||
|
|
||||||
The Maven coordinates of this project are `space.kscience:magix-api:0.1.1-SNAPSHOT`.
|
The Maven coordinates of this project are `space.kscience:magix-api:0.2.0`.
|
||||||
|
|
||||||
**Gradle Groovy:**
|
|
||||||
```groovy
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://repo.kotlin.link' }
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'space.kscience:magix-api:0.1.1-SNAPSHOT'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**Gradle Kotlin DSL:**
|
**Gradle Kotlin DSL:**
|
||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
|
//uncomment to access development builds
|
||||||
|
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("space.kscience:magix-api:0.1.1-SNAPSHOT")
|
implementation("space.kscience:magix-api:0.2.0")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
271
magix/magix-api/api/magix-api.api
Normal file
271
magix/magix-api/api/magix-api.api
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
public abstract interface class space/kscience/magix/api/MagixEndpoint {
|
||||||
|
public static final field Companion Lspace/kscience/magix/api/MagixEndpoint$Companion;
|
||||||
|
public static final field DEFAULT_MAGIX_HTTP_PORT I
|
||||||
|
public static final field DEFAULT_MAGIX_RAW_PORT I
|
||||||
|
public static final field DEFAULT_MAGIX_ZMQ_PUB_PORT I
|
||||||
|
public static final field DEFAULT_MAGIX_ZMQ_PULL_PORT I
|
||||||
|
public abstract fun broadcast (Lspace/kscience/magix/api/MagixMessage;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public abstract fun close ()V
|
||||||
|
public abstract fun subscribe (Lspace/kscience/magix/api/MagixMessageFilter;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public static synthetic fun subscribe$default (Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixMessageFilter;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixEndpoint$Companion {
|
||||||
|
public static final field DEFAULT_MAGIX_HTTP_PORT I
|
||||||
|
public static final field DEFAULT_MAGIX_RAW_PORT I
|
||||||
|
public static final field DEFAULT_MAGIX_ZMQ_PUB_PORT I
|
||||||
|
public static final field DEFAULT_MAGIX_ZMQ_PULL_PORT I
|
||||||
|
public final fun getMagixJson ()Lkotlinx/serialization/json/Json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixEndpointKt {
|
||||||
|
public static final fun send (Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixMessage;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/magix/api/MagixFlowPlugin {
|
||||||
|
public abstract fun start (Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
|
public fun start (Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/flow/MutableSharedFlow;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixFormat {
|
||||||
|
public fun <init> (Lkotlinx/serialization/KSerializer;Ljava/util/Set;)V
|
||||||
|
public final fun component1 ()Lkotlinx/serialization/KSerializer;
|
||||||
|
public final fun component2 ()Ljava/util/Set;
|
||||||
|
public final fun copy (Lkotlinx/serialization/KSerializer;Ljava/util/Set;)Lspace/kscience/magix/api/MagixFormat;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/magix/api/MagixFormat;Lkotlinx/serialization/KSerializer;Ljava/util/Set;ILjava/lang/Object;)Lspace/kscience/magix/api/MagixFormat;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getDefaultFormat ()Ljava/lang/String;
|
||||||
|
public final fun getFormats ()Ljava/util/Set;
|
||||||
|
public final fun getSerializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixFormatKt {
|
||||||
|
public static final fun send (Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixFormat;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun send$default (Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixFormat;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||||
|
public static final fun subscribe (Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixFormat;Ljava/util/Collection;Ljava/util/Collection;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
public static synthetic fun subscribe$default (Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixFormat;Ljava/util/Collection;Ljava/util/Collection;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessage {
|
||||||
|
public static final field Companion Lspace/kscience/magix/api/MagixMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun component1 ()Ljava/lang/String;
|
||||||
|
public final fun component2 ()Lkotlinx/serialization/json/JsonElement;
|
||||||
|
public final fun component3 ()Ljava/lang/String;
|
||||||
|
public final fun component4 ()Ljava/lang/String;
|
||||||
|
public final fun component5 ()Ljava/lang/String;
|
||||||
|
public final fun component6 ()Ljava/lang/String;
|
||||||
|
public final fun component7 ()Lkotlinx/serialization/json/JsonElement;
|
||||||
|
public final fun copy (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lspace/kscience/magix/api/MagixMessage;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/magix/api/MagixMessage;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lspace/kscience/magix/api/MagixMessage;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getFormat ()Ljava/lang/String;
|
||||||
|
public final fun getId ()Ljava/lang/String;
|
||||||
|
public final fun getParentId ()Ljava/lang/String;
|
||||||
|
public final fun getPayload ()Lkotlinx/serialization/json/JsonElement;
|
||||||
|
public final fun getSourceEndpoint ()Ljava/lang/String;
|
||||||
|
public final fun getTargetEndpoint ()Ljava/lang/String;
|
||||||
|
public final fun getUser ()Lkotlinx/serialization/json/JsonElement;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/magix/api/MagixMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/magix/api/MagixMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/magix/api/MagixMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/magix/api/MagixMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessageFilter {
|
||||||
|
public static final field Companion Lspace/kscience/magix/api/MagixMessageFilter$Companion;
|
||||||
|
public fun <init> ()V
|
||||||
|
public synthetic fun <init> (ILjava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;)V
|
||||||
|
public synthetic fun <init> (Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun accepts (Lspace/kscience/magix/api/MagixMessage;)Z
|
||||||
|
public final fun component1 ()Ljava/util/Collection;
|
||||||
|
public final fun component2 ()Ljava/util/Collection;
|
||||||
|
public final fun component3 ()Ljava/util/Collection;
|
||||||
|
public final fun copy (Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;)Lspace/kscience/magix/api/MagixMessageFilter;
|
||||||
|
public static synthetic fun copy$default (Lspace/kscience/magix/api/MagixMessageFilter;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;ILjava/lang/Object;)Lspace/kscience/magix/api/MagixMessageFilter;
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getFormat ()Ljava/util/Collection;
|
||||||
|
public final fun getSource ()Ljava/util/Collection;
|
||||||
|
public final fun getTarget ()Ljava/util/Collection;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/magix/api/MagixMessageFilter;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessageFilter$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/magix/api/MagixMessageFilter$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/magix/api/MagixMessageFilter;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/magix/api/MagixMessageFilter;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessageFilter$Companion {
|
||||||
|
public final fun getALL ()Lspace/kscience/magix/api/MagixMessageFilter;
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessageFilterKt {
|
||||||
|
public static final fun filter (Lkotlinx/coroutines/flow/Flow;Lspace/kscience/magix/api/MagixMessageFilter;)Lkotlinx/coroutines/flow/Flow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/api/MagixMessageKt {
|
||||||
|
public static final fun getUserName (Lspace/kscience/magix/api/MagixMessage;)Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/ConvertersKt {
|
||||||
|
public static final fun launchMagixConverter (Lkotlinx/coroutines/CoroutineScope;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixMessageFilter;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||||
|
public static synthetic fun launchMagixConverter$default (Lkotlinx/coroutines/CoroutineScope;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixMessageFilter;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixPortalKt {
|
||||||
|
public static final fun launchMagixPortal (Lkotlinx/coroutines/CoroutineScope;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixMessageFilter;Lspace/kscience/magix/api/MagixMessageFilter;)Lkotlinx/coroutines/Job;
|
||||||
|
public static synthetic fun launchMagixPortal$default (Lkotlinx/coroutines/CoroutineScope;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/api/MagixMessageFilter;Lspace/kscience/magix/api/MagixMessageFilter;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/magix/services/MagixRegistry {
|
||||||
|
public abstract fun get (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryErrorMessage : space/kscience/magix/services/MagixRegistryMessage {
|
||||||
|
public static final field Companion Lspace/kscience/magix/services/MagixRegistryErrorMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public final fun getErrorMessage ()Ljava/lang/String;
|
||||||
|
public final fun getErrorType ()Ljava/lang/String;
|
||||||
|
public fun getPropertyName ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/magix/services/MagixRegistryErrorMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryErrorMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/magix/services/MagixRegistryErrorMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/magix/services/MagixRegistryErrorMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/magix/services/MagixRegistryErrorMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryErrorMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryKt {
|
||||||
|
public static final fun getProperty (Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public static synthetic fun getProperty$default (Lspace/kscience/magix/api/MagixEndpoint;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||||
|
public static final fun launchMagixRegistry (Lkotlinx/coroutines/CoroutineScope;Ljava/lang/String;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/services/MagixRegistry;Ljava/util/Collection;Ljava/util/Collection;)Lkotlinx/coroutines/Job;
|
||||||
|
public static synthetic fun launchMagixRegistry$default (Lkotlinx/coroutines/CoroutineScope;Ljava/lang/String;Lspace/kscience/magix/api/MagixEndpoint;Lspace/kscience/magix/services/MagixRegistry;Ljava/util/Collection;Ljava/util/Collection;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class space/kscience/magix/services/MagixRegistryMessage {
|
||||||
|
public static final field Companion Lspace/kscience/magix/services/MagixRegistryMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public abstract fun getPropertyName ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/magix/services/MagixRegistryMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryMessage$Companion {
|
||||||
|
public final fun getFormat ()Lspace/kscience/magix/api/MagixFormat;
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryModifyMessage : space/kscience/magix/services/MagixRegistryMessage {
|
||||||
|
public static final field Companion Lspace/kscience/magix/services/MagixRegistryModifyMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)V
|
||||||
|
public fun getPropertyName ()Ljava/lang/String;
|
||||||
|
public final fun getValue ()Lkotlinx/serialization/json/JsonElement;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/magix/services/MagixRegistryModifyMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryModifyMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/magix/services/MagixRegistryModifyMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/magix/services/MagixRegistryModifyMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/magix/services/MagixRegistryModifyMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryModifyMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryRequestMessage : space/kscience/magix/services/MagixRegistryMessage {
|
||||||
|
public static final field Companion Lspace/kscience/magix/services/MagixRegistryRequestMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;)V
|
||||||
|
public fun getPropertyName ()Ljava/lang/String;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/magix/services/MagixRegistryRequestMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryRequestMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/magix/services/MagixRegistryRequestMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/magix/services/MagixRegistryRequestMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/magix/services/MagixRegistryRequestMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryRequestMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryValueMessage : space/kscience/magix/services/MagixRegistryMessage {
|
||||||
|
public static final field Companion Lspace/kscience/magix/services/MagixRegistryValueMessage$Companion;
|
||||||
|
public synthetic fun <init> (ILjava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)V
|
||||||
|
public fun getPropertyName ()Ljava/lang/String;
|
||||||
|
public final fun getValue ()Lkotlinx/serialization/json/JsonElement;
|
||||||
|
public static final synthetic fun write$Self (Lspace/kscience/magix/services/MagixRegistryValueMessage;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryValueMessage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||||
|
public static final field INSTANCE Lspace/kscience/magix/services/MagixRegistryValueMessage$$serializer;
|
||||||
|
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||||
|
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/magix/services/MagixRegistryValueMessage;
|
||||||
|
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||||
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
|
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/magix/services/MagixRegistryValueMessage;)V
|
||||||
|
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class space/kscience/magix/services/MagixRegistryValueMessage$Companion {
|
||||||
|
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface class space/kscience/magix/services/MutableMagixRegistry {
|
||||||
|
public abstract fun set (Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlinx/serialization/json/JsonElement;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,14 @@
|
|||||||
|
import space.kscience.gradle.Maturity
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description = """
|
||||||
|
A kotlin API for magix standard and some zero-dependency magix services
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
kscience {
|
kscience {
|
||||||
jvm()
|
jvm()
|
||||||
js()
|
js()
|
||||||
@ -13,3 +19,6 @@ kscience {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readme{
|
||||||
|
maturity = Maturity.EXPERIMENTAL
|
||||||
|
}
|
||||||
|
@ -54,3 +54,8 @@ public interface MagixEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An alias for [MagixEndpoint.send]
|
||||||
|
*/
|
||||||
|
public suspend fun MagixEndpoint.send(message: MagixMessage): Unit = broadcast(message)
|
@ -2,8 +2,28 @@ package space.kscience.magix.api
|
|||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A plugin that could be inserted into basic loop implementation.
|
||||||
|
*/
|
||||||
public fun interface MagixFlowPlugin {
|
public fun interface MagixFlowPlugin {
|
||||||
public fun start(scope: CoroutineScope, magixFlow: MutableSharedFlow<MagixMessage>): Job
|
|
||||||
|
/**
|
||||||
|
* Attach a [Job] to magix loop.
|
||||||
|
* Receive messages from [receive].
|
||||||
|
* Send messages via [sendMessage]
|
||||||
|
*/
|
||||||
|
public fun start(
|
||||||
|
scope: CoroutineScope,
|
||||||
|
receive: Flow<MagixMessage>,
|
||||||
|
sendMessage: suspend (MagixMessage) -> Unit,
|
||||||
|
): Job
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the same [MutableSharedFlow] to send and receive messages. Could be a bottleneck in case of many plugins.
|
||||||
|
*/
|
||||||
|
public fun start(scope: CoroutineScope, magixFlow: MutableSharedFlow<MagixMessage>): Job =
|
||||||
|
start(scope, magixFlow) { magixFlow.emit(it) }
|
||||||
}
|
}
|
@ -6,6 +6,11 @@ import kotlinx.serialization.KSerializer
|
|||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import space.kscience.magix.api.MagixEndpoint.Companion.magixJson
|
import space.kscience.magix.api.MagixEndpoint.Companion.magixJson
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A format for [MagixMessage] that allows to decode typed payload
|
||||||
|
*
|
||||||
|
* @param formats allowed values of the format field that are processed. The first value is the primary format for sending.
|
||||||
|
*/
|
||||||
public data class MagixFormat<T>(
|
public data class MagixFormat<T>(
|
||||||
val serializer: KSerializer<T>,
|
val serializer: KSerializer<T>,
|
||||||
val formats: Set<String>,
|
val formats: Set<String>,
|
||||||
@ -13,31 +18,40 @@ public data class MagixFormat<T>(
|
|||||||
val defaultFormat: String get() = formats.firstOrNull() ?: "magix"
|
val defaultFormat: String get() = formats.firstOrNull() ?: "magix"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe for messages in given endpoint using [format] to declare format filter as well as automatic decoding.
|
||||||
|
*
|
||||||
|
* @return a flow of pairs (raw message, decoded message). Raw messages are to be used to extract headers.
|
||||||
|
*/
|
||||||
public fun <T> MagixEndpoint.subscribe(
|
public fun <T> MagixEndpoint.subscribe(
|
||||||
format: MagixFormat<T>,
|
format: MagixFormat<T>,
|
||||||
originFilter: Collection<String?>? = null,
|
originFilter: Collection<String>? = null,
|
||||||
targetFilter: Collection<String?>? = null,
|
targetFilter: Collection<String>? = null,
|
||||||
): Flow<Pair<MagixMessage, T>> = subscribe(
|
): Flow<Pair<MagixMessage, T>> = subscribe(
|
||||||
MagixMessageFilter(format = format.formats, origin = originFilter, target = targetFilter)
|
MagixMessageFilter(format = format.formats, source = originFilter, target = targetFilter)
|
||||||
).map {
|
).map {
|
||||||
val value: T = magixJson.decodeFromJsonElement(format.serializer, it.payload)
|
val value: T = magixJson.decodeFromJsonElement(format.serializer, it.payload)
|
||||||
it to value
|
it to value
|
||||||
}
|
}
|
||||||
|
|
||||||
public suspend fun <T> MagixEndpoint.broadcast(
|
/**
|
||||||
|
* Send a message using given [format] to encode the message payload. The format field is also taken from [format].
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public suspend fun <T> MagixEndpoint.send(
|
||||||
format: MagixFormat<T>,
|
format: MagixFormat<T>,
|
||||||
payload: T,
|
payload: T,
|
||||||
|
source: String,
|
||||||
target: String? = null,
|
target: String? = null,
|
||||||
id: String? = null,
|
id: String? = null,
|
||||||
parentId: String? = null,
|
parentId: String? = null,
|
||||||
user: JsonElement? = null,
|
user: JsonElement? = null,
|
||||||
origin: String = format.defaultFormat,
|
|
||||||
) {
|
) {
|
||||||
val message = MagixMessage(
|
val message = MagixMessage(
|
||||||
format = format.defaultFormat,
|
format = format.defaultFormat,
|
||||||
payload = magixJson.encodeToJsonElement(format.serializer, payload),
|
payload = magixJson.encodeToJsonElement(format.serializer, payload),
|
||||||
origin = origin,
|
sourceEndpoint = source,
|
||||||
target = target,
|
targetEndpoint = target,
|
||||||
id = id,
|
id = id,
|
||||||
parentId = parentId,
|
parentId = parentId,
|
||||||
user = user
|
user = user
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package space.kscience.magix.api
|
package space.kscience.magix.api
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.*
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -27,9 +27,20 @@ import kotlinx.serialization.json.JsonElement
|
|||||||
public data class MagixMessage(
|
public data class MagixMessage(
|
||||||
val format: String,
|
val format: String,
|
||||||
val payload: JsonElement,
|
val payload: JsonElement,
|
||||||
val origin: String,
|
val sourceEndpoint: String,
|
||||||
val target: String? = null,
|
val targetEndpoint: String? = null,
|
||||||
val id: String? = null,
|
val id: String? = null,
|
||||||
val parentId: String? = null,
|
val parentId: String? = null,
|
||||||
val user: JsonElement? = null,
|
val user: JsonElement? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default accessor for username. If `user` is an object, take it's "name" field.
|
||||||
|
* If it is primitive, take its content. Return "@error" if it is an array.
|
||||||
|
*/
|
||||||
|
public val MagixMessage.userName: String? get() = when(user){
|
||||||
|
null, JsonNull -> null
|
||||||
|
is JsonObject -> user.jsonObject["name"]?.jsonPrimitive?.content
|
||||||
|
is JsonPrimitive -> user.content
|
||||||
|
else -> "@error"
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user