Plc4X refactor
This commit is contained in:
parent
58675f72f5
commit
977500223d
@ -11,14 +11,14 @@ description = """
|
||||
A plugin for Controls-kt device server on top of plc4x library
|
||||
""".trimIndent()
|
||||
|
||||
kscience{
|
||||
kscience {
|
||||
jvm()
|
||||
jvmMain{
|
||||
jvmMain {
|
||||
api(projects.controlsCore)
|
||||
api("org.apache.plc4x:plc4j-spi:$plc4xVersion")
|
||||
}
|
||||
}
|
||||
|
||||
readme{
|
||||
readme {
|
||||
maturity = Maturity.EXPERIMENTAL
|
||||
}
|
@ -2,27 +2,75 @@ package space.kscience.controls.plc4x
|
||||
|
||||
import kotlinx.coroutines.future.await
|
||||
import org.apache.plc4x.java.api.PlcConnection
|
||||
import org.apache.plc4x.java.api.messages.PlcBrowseItem
|
||||
import org.apache.plc4x.java.api.messages.PlcTagResponse
|
||||
import org.apache.plc4x.java.api.messages.PlcWriteRequest
|
||||
import org.apache.plc4x.java.api.messages.PlcWriteResponse
|
||||
import org.apache.plc4x.java.api.types.PlcResponseCode
|
||||
import space.kscience.controls.api.Device
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
|
||||
public interface Plc4XDevice: Device {
|
||||
public val connection: PlcConnection
|
||||
private val PlcTagResponse.responseCodes: Map<String, PlcResponseCode>
|
||||
get() = tagNames.associateWith { getResponseCode(it) }
|
||||
|
||||
public suspend fun read(plc4xProperty: Plc4xProperty): Meta = with(plc4xProperty){
|
||||
val request = connection.readRequestBuilder().request().build()
|
||||
val response = request.execute().await()
|
||||
response.readProperty()
|
||||
}
|
||||
|
||||
public suspend fun write(plc4xProperty: Plc4xProperty, value: Meta): Unit = with(plc4xProperty){
|
||||
val request: PlcWriteRequest = connection.writeRequestBuilder().writeProperty(value).build()
|
||||
request.execute().await()
|
||||
}
|
||||
|
||||
public suspend fun subscribe(propertyName: String, plc4xProperty: Plc4xProperty): Unit = with(plc4xProperty){
|
||||
|
||||
}
|
||||
private val Map<String, PlcResponseCode>.isOK get() = values.all { it == PlcResponseCode.OK }
|
||||
|
||||
public class PlcException(public val codes: Map<String, PlcResponseCode>) : Exception() {
|
||||
override val message: String
|
||||
get() = "Plc request unsuccessful:" + codes.entries.joinToString(prefix = "\n\t", separator = "\n\t") {
|
||||
"${it.key}: ${it.value.name}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun PlcTagResponse.throwOnFail() {
|
||||
val codes = responseCodes
|
||||
if (!codes.isOK) throw PlcException(codes)
|
||||
}
|
||||
|
||||
|
||||
public interface Plc4XDevice : Device {
|
||||
public val connection: PlcConnection
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send ping request and suspend until it comes back
|
||||
*/
|
||||
public suspend fun Plc4XDevice.ping(): PlcResponseCode = connection.ping().await().responseCode
|
||||
|
||||
/**
|
||||
* Send browse request to list available tags
|
||||
*/
|
||||
public suspend fun Plc4XDevice.browse(): Map<String, MutableList<PlcBrowseItem>> {
|
||||
require(connection.metadata.isBrowseSupported){"Browse actions are not supported on connection"}
|
||||
val request = connection.browseRequestBuilder().build()
|
||||
val response = request.execute().await()
|
||||
|
||||
return response.queryNames.associateWith { response.getValues(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Send read request and suspend until it returns. Throw a [PlcException] if at least one tag read fails.
|
||||
*
|
||||
* @throws PlcException
|
||||
*/
|
||||
public suspend fun Plc4XDevice.read(plc4xProperty: Plc4xProperty): Meta = with(plc4xProperty) {
|
||||
require(connection.metadata.isReadSupported) {"Read actions are not supported on connections"}
|
||||
val request = connection.readRequestBuilder().request().build()
|
||||
val response = request.execute().await()
|
||||
response.throwOnFail()
|
||||
response.readProperty()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send write request and suspend until it finishes. Throw a [PlcException] if at least one tag write fails.
|
||||
*
|
||||
* @throws PlcException
|
||||
*/
|
||||
public suspend fun Plc4XDevice.write(plc4xProperty: Plc4xProperty, value: Meta): Unit = with(plc4xProperty) {
|
||||
require(connection.metadata.isWriteSupported){"Write actions are not supported on connection"}
|
||||
val request: PlcWriteRequest = connection.writeRequestBuilder().writeProperty(value).build()
|
||||
val response: PlcWriteResponse = request.execute().await()
|
||||
response.throwOnFail()
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package space.kscience.controls.plc4x
|
||||
|
||||
import org.apache.plc4x.java.api.PlcConnection
|
||||
import space.kscience.controls.spec.DeviceActionSpec
|
||||
import space.kscience.controls.spec.DeviceBase
|
||||
import space.kscience.controls.spec.DevicePropertySpec
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
|
||||
public class Plc4XDeviceBase(
|
||||
context: Context,
|
||||
meta: Meta,
|
||||
override val connection: PlcConnection,
|
||||
) : Plc4XDevice, DeviceBase<Plc4XDevice>(context, meta) {
|
||||
override val properties: Map<String, DevicePropertySpec<Plc4XDevice, *>>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val actions: Map<String, DeviceActionSpec<Plc4XDevice, *, *>> = emptyMap()
|
||||
|
||||
override fun toString(): String {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
@ -8,6 +8,8 @@ import space.kscience.dataforge.meta.Meta
|
||||
|
||||
public interface Plc4xProperty {
|
||||
|
||||
public val keys: Set<String>
|
||||
|
||||
public fun PlcReadRequest.Builder.request(): PlcReadRequest.Builder
|
||||
|
||||
public fun PlcReadResponse.readProperty(): Meta
|
||||
@ -15,17 +17,23 @@ public interface Plc4xProperty {
|
||||
public fun PlcWriteRequest.Builder.writeProperty(meta: Meta): PlcWriteRequest.Builder
|
||||
}
|
||||
|
||||
public class DefaultPlc4xProperty(
|
||||
private class DefaultPlc4xProperty(
|
||||
private val address: String,
|
||||
private val plcValueType: PlcValueType,
|
||||
private val name: String = "@default",
|
||||
) : Plc4xProperty {
|
||||
|
||||
override val keys: Set<String> = setOf(name)
|
||||
|
||||
override fun PlcReadRequest.Builder.request(): PlcReadRequest.Builder =
|
||||
addTagAddress(name, address)
|
||||
|
||||
override fun PlcReadResponse.readProperty(): Meta =
|
||||
asPlcValue.toMeta()
|
||||
getPlcValue(name).toMeta()
|
||||
|
||||
override fun PlcWriteRequest.Builder.writeProperty(meta: Meta): PlcWriteRequest.Builder =
|
||||
addTagAddress(name, address, meta.toPlcValue(plcValueType))
|
||||
}
|
||||
|
||||
public fun Plc4xProperty(address: String, plcValueType: PlcValueType, name: String = "@default"): Plc4xProperty =
|
||||
DefaultPlc4xProperty(address, plcValueType, name)
|
@ -84,24 +84,24 @@ private fun Context.launchPidDevice(
|
||||
|
||||
showDashboard {
|
||||
plot {
|
||||
plotNumberState(context, state, maxAge = maxAge) {
|
||||
plotNumberState(context, state, maxAge = maxAge, sampling = 50.milliseconds) {
|
||||
name = "real position"
|
||||
}
|
||||
plotDeviceProperty(device.pid, Regulator.position.name, maxAge = maxAge) {
|
||||
plotDeviceProperty(device.pid, Regulator.position.name, maxAge = maxAge, sampling = 50.milliseconds) {
|
||||
name = "read position"
|
||||
}
|
||||
|
||||
plotDeviceProperty(device.pid, Regulator.target.name, maxAge = maxAge) {
|
||||
plotDeviceProperty(device.pid, Regulator.target.name, maxAge = maxAge, sampling = 50.milliseconds) {
|
||||
name = "target"
|
||||
}
|
||||
}
|
||||
|
||||
plot {
|
||||
plotDeviceProperty(device.start, LimitSwitch.locked.name, maxAge = maxAge) {
|
||||
plotDeviceProperty(device.start, LimitSwitch.locked.name, maxAge = maxAge, sampling = 50.milliseconds) {
|
||||
name = "start measured"
|
||||
mode = ScatterMode.markers
|
||||
}
|
||||
plotDeviceProperty(device.end, LimitSwitch.locked.name, maxAge = maxAge) {
|
||||
plotDeviceProperty(device.end, LimitSwitch.locked.name, maxAge = maxAge, sampling = 50.milliseconds) {
|
||||
name = "end measured"
|
||||
mode = ScatterMode.markers
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user